Больше чем меньше чем больше чем что-то подозрительное

45

Для заданной строки длиной N знаков «меньше» и «больше чем» ( <, >) вставьте целые числа от 0 до N в начале и в конце каждой пары знаков так, чтобы все неравенства были выполнены. Выведите полученную строку. Если имеется несколько допустимых выходов, выведите любой (и только один) из них.

Например

<<><><<

имеет 7 символов, поэтому необходимо вставить все цифры от 0 до 7 включительно. Действительный вывод

2<3<4>1<5>0<6<7

потому что все неравенства приняты по одному

2<3
3<4
4>1
1<5
5>0
0<6
6<7

это правда.

При желании на выходе могут быть пробелы вокруг знаков, например 2 < 3 < 4 > 1 < 5 > 0 < 6 < 7.

Самый короткий код в байтах побеждает.

Тестовые случаи

Первая строка после пустой строки - это входные данные, а каждая следующая строка - допустимые примеры вывода.

[empty string]
0

<
0<1

>
1>0

<<
0<1<2

<>
1<2>0

><
1>0<2
2>0<1

>>
2>1>0

<<<
0<1<2<3

><>
1>0<3>2

>><
3>2>0<1
3>1>0<2
2>1>0<3

>>>
3>2>1>0

>>><<<
3>2>1>0<4<5<6
6>3>1>0<2<4<5
4>2>1>0<3<5<6
4>3>1>0<2<5<6

<<><><<
2<3<4>1<5>0<6<7

>><><>>
7>6>0<5>1<4>3>2

<<<<<<<<<<<<<<
0<1<2<3<4<5<6<7<8<9<10<11<12<13<14

>><<<<><>><><<
6>5>4<7<8<9<10>3<11>2>1<12>0<13<14
14>5>4<7<8<9<10>3<11>2>1<12>0<13<6
Кальвин Хобби
источник
4
Всегда ли будет действительный вывод?
mbomb007
3
@ mbomb007 Да. Там всегда есть хотя бы один.
Увлечения Кэлвина
23
Я хочу, чтобы кто-то запрограммировал это в> <>! Это было бы круто (и иронично, я думаю?)
Сорен
Это было действительно весело, но просто испытание, спасибо оп
Shaun Wild

Ответы:

29

Сетчатка , 20 байт

Число байтов предполагает кодировку ISO 8859-1.


$.'
S`>
%O#`\d+
¶
>

Попробуйте онлайн! (Первая строка включает набор тестов, разделенных переводом строки.)

объяснение

Простой способ , чтобы найти действительную перестановку, чтобы начать путем вставки цифры от 0до Nв порядке, а затем в обратном число , окружающее каждую подстроку >с. Возьмите <><<>>><<в качестве примера:

0<1>2<3<4>5>6>7<8<9
  ---   -------      these sections are wrong, so we reverse them
0<2>1<3<7>6>5>4<8<9

Обе эти задачи довольно просты в Retina, хотя все, с чем мы действительно можем работать, это строки. Мы можем сохранить дополнительный байт, вставив числа Nснизу 0и перевернув окружающие секции <, но принцип тот же.

Этап 1: Замена


$.'

Мы начинаем с вставки длины $'(суффикса, то есть всего после совпадения) в каждую возможную позицию на входе. Это вставит цифры от Nвниз до 0.

Этап 2: Сплит

S`>

Мы разбиваем входные данные >на отдельные строки, поэтому каждая строка представляет собой либо отдельный номер, либо список чисел, с которыми соединяются <.

Этап 3: сортировка

%O#`\d+

Внутри каждой строки ( %) мы сортируем ( O) числа ( \d#) по их числовому значению ( #). Так как мы вставили число в обратном числовом порядке, это переворачивает их.

Этап 4: Замена

¶
>

Мы >снова превращаем перевод строки, чтобы объединить все обратно в одну строку. Вот и все.

В качестве примечания я хотел добавить способ применения %к другим разделителям, кроме перевода строки. Если бы я уже сделал это, это представление было бы 14 байтами, потому что тогда три последних этапа были бы сведены к одному:

%'>O#`\d+
Мартин Эндер
источник
Как это, как один восьмой мой размер? Хорошо сделано.
ThreeFx
@ThreeFx Потому что я не использую грубую силу. ;) Пояснение придет через минуту.
Мартин Эндер
22

> <> , 46 43 35 + 4 для  -s== 39 байт

0&l?!v:3%?\&:n1+$o!
+nf0.>&n; >l&:@

Это реализация алгоритма xnor в> <>.

Он принимает входную строку в стеке ( -sфлаг со стандартным интерпретатором).

Вы можете попробовать это на онлайн-переводчике .

Аарон
источник
2
> <> кажется подходящим языком для этой задачи.
Анаксимандр
21

> <> , 26 + 4 = 30 байт

l22pirv
1+$2po>:3%::2g:n$-

Попробуйте онлайн! +4 байта для -s=флага - если -sвсе в порядке (это будет означать, что флаг должен быть полностью удален для пустого ввода), тогда это будет +3 вместо этого.

Предполагается, что вход STDIN является пустым, так что iвыдает -1 (что он делает в EOF). Ошибка программы при попытке напечатать это -1 как символ.

Использует максимальное количество подходов >, минимальное количество <подходов.

[Setup]
l22p         Place (length of stack) = (length of input) into position (2, 2) of
             the codebox. Codebox values are initialised to 0, so (0, 2) will
             contain the other value we need.
i            Push -1 due to EOF so that we error out later
r            Reverse the stack
v            Move down to the next line
>            Change IP direction to rightward

[Loop]
:3%          Take code point of '<' or '>' mod 3, giving 0 or 2 respectively
             (call this value c)
:            Duplicate
:2g          Fetch the value v at (c, 2)
:n           Output it as a number
$-1+         Calculate v-c+1 to update v
$2p          Place the updated value into (c, 2)
o            Output the '<' or '>' as a char (or error out here outputting -1)

Программа, которая выходит чисто и не делает предположения о STDIN, составляет 4 дополнительных байта:

l22p0rv
p:?!;o>:3%::2g:n$-1+$2
Sp3000
источник
11

Perl, 29 байт

Включает +2 для -lp

Запустить с вводом на STDIN, например

order.pl <<< "<<><><<"

Выход:

0<1<7>2<6>3<4<5

order.pl:

#!/usr/bin/perl -lp
s%%/\G</?$a++:y///c-$b++%eg

объяснение

Имейте два счетчика, максимум начинающийся с длины строки, минимум начинающийся с 0. Затем на каждой границе (включая начало и конец строки), если он находится непосредственно перед <положением минимума туда и увеличивайте на 1, в противном случае ставьте максимум там и уменьшайте на 1 (в конце строки не имеет значения, какой счетчик вы используете, так как они оба одинаковы)

Тон Хоспел
источник
s{}{/\G/...}Я никогда не видел этого раньше, это блестяще.
Примо
10

Python 2, 67 байт

f=lambda s,i=0:s and`i+len(s)*(s>'=')`+s[0]+f(s[1:],i+(s<'>'))or`i`

Рекурсивная функция. Удовлетворяет каждого оператора по очереди, выставляя наименьшее неиспользованное значение xдля x<и наибольшее для x>. Наименьшее неиспользуемое значение сохраняется iи обновляется, а наибольшее неиспользуемое значение определяется iпо оставшейся длине.

XNOR
источник
1
Я думаю, вы могли бы сделать (s>'=')вместо того, (s>='>')чтобы сохранить байт?
Матмандан
@mathmandan Спасибо! Это странно <и >не является последовательной кодовой точкой.
xnor
Согласовано! Но я думаю, я вижу, как было бы целесообразно иметь =между <и >.
Матмандан
8

Python 2, 163 137 байт

from random import*
def f(v):l=len(v)+1;N=''.join(sum(zip(sample(map(str,range(l)),l),v+' '),()));return N if eval(N)or len(v)<1else f(v)

Перетасовывает числа до тех пор, пока утверждение не укажет True.

Попробуй.

atlasologist
источник
Это явно самый разумный из всех ответов.
moopet
7

APL, 33 байта

⍞←(S,⊂''),.,⍨-1-⍋⍋+\0,1-2×'>'=S←⍞

⍋⍋ необычайно полезен.

объяснение

⍞←(S,⊂''),.,⍨-1-⍋⍋+\0,1-2×'>'=S←⍞
                                   ⍞ read a string from stdin      '<<><><<'
                                 S←   store it in variable S
                             '>'=     test each character for eq.   0 0 1 0 1 0 0
                         1-2×         1-2×0 = 1, 1-2×1 = ¯1         1 1 ¯1 1 ¯1 1 1
                                      (thus, 1 if < else ¯1)
                       0,             concatenate 0 to the vector   0 1 1 ¯1 1 ¯1 1 1
                     +\               calculate its running sum     0 1 2 1 2 1 2 3
                   ⍋                 create a vector of indices    1 2 4 6 3 5 7 8
                                      that sort the vector in
                                      ascending order
                 ⍋                   do it again: the compound ⍋⍋ 1 2 5 3 6 4 7 8
                                      maps a vector V to another
                                      vector V', one permutation of
                                      the set of the indices of V,
                                      such that
                                            V > V  => V' > V'.
                                             i   j     i    j
                                      due to this property, V and V'
                                      get sorted in the same way:
                                          ⍋V = ⍋V' = ⍋⍋⍋V.
              -1-                     decrement by one              0 1 4 2 5 3 6 7
      ⊂''                            void character vector         ⊂''
    S,                                concatenate input string     '<<><><<' ⊂''
   (     ),.,⍨                       first concatenate each        0 '<' 1 '<' 4 '>' 2 \
                                     element of the result vector  '<' 5 '>' 3 '<' 6 '<' \
                                     with the cordisponding        7 ⊂''
                                     element in the input string,
                                     then concatenate each result
⍞←                                  write to stdout
Oberon
источник
3
Что делают елки ( ⍋⍋)?
Конор О'Брайен
это оценка, которая возвращает признаки в отсортированном порядке. Сделав это дважды, вы получите, 1где было наименьшее число, 2где было следующее наименьшее число, ect.
Цвей
@ ConorO'Brien отредактировано с коротким объяснением.
Оберон
Да, очень короткий.
Конор О'Брайен
7

JavaScript (ES6), 74 56 байт

s=>s.replace(/./g,c=>(c<'>'?j++:l--)+c,j=0,l=s.length)+j

Начинается с набора чисел 0...N. На каждом этапе просто берется наибольшее ( l) или наименьшее ( j) из оставшихся чисел; следующее число по определению должно быть меньше или больше этого. Редактировать: благодаря @Arnauld сэкономлено 18 байт.

Нил
источник
3
Вы можете использовать replace? Возможноs=>s.replace(/./g,c=>(c<'>'?j++:l--)+c,j=0,l=s.length)+j
Арно
@Arnauld ... и я подумал, что хорошо справляюсь со своей первой попыткой игры в гольф (которая не поддается замене replace) до 74 байтов ...
Нил
5

Pyth - 19 байт

Ура для сравнения цепочки!

!QZhv#ms.idQ.p`Mhl

Не работает онлайн потому что Eval безопасности.

Maltysen
источник
4

2sable , 20 байтов

gUvy'<Qi¾¼ëXD<U}y}XJ

объяснение

gU                     # store input length in variable X
  v              }     # for each char in input
   y'<Qi               # if current char is "<"
        ¾¼             # push counter (initialized as 0), increase counter
          ëXD<U}       # else, push X and decrease value in variable X
                y      # push current char
                  XJ   # push the final number and join the stack

Попробуйте онлайн!

Для N <10 это могло быть 14 байтов:

ÎvyN>}J'<¡í'<ý
Emigna
источник
4

C #, 102 99 байт

string f(string s){int i=0,j=s.Length;var r="";foreach(var c in s)r=r+(c<61?i++:j--)+c;return r+i;}

Ungolfed:

string f(string s)
{
    int i = 0, j = s.Length;    // Used to track the lowest and highest unused number.
    var r = "";                 // Start with the empty string.

    foreach (var c in s)        // For each character in the input string:
        r = r +                 // Append to the result:
            (c < 61             // If the current character is '<':
                ? i++           // Insert the lowest unused number,
                : j--)          // otherwise, insert the highest unused number.
            + c;                // And append the current character.

    return r + i;               // Return the result with the last unused number appended.
}
Scepheo
источник
Я устал, поэтому я мог что-то упустить, но не поменял ли бы r = r +часть на составное назначение, сэкономив пару байтов?
Carcigenicate
2
Нет - r+часть с правой стороны сообщает компилятору, что все это строка, поэтому используется строковое представление c. Если бы я использовал r+=, ?:часть оценивалась бы как a int, к ней cдобавлялось бы порядковое значение , и только тогда она была бы преобразована в ее строковое представление.
Скефео
4

Java 8, 126 125 байт

s->{int t=s.replaceAll("<","").length(),y=t-1;String r=t+++"";for(char c:s.toCharArray())r+=(c+"")+(c<61?t++:y--);return r;};

Я не думаю, что это даже работает, хе-хе

Тестовая программа Ungolfed

public static void main(String[] args) {
    Function<String, String> function = s -> {
        int t = s.replaceAll("<", "").length(), y = t - 1;
        String r = t++ + "";
        for (char c : s.toCharArray()) {
            r += (c + "") + (c < 61 ? t++ : y--);
        }
        return r;
    };

    System.out.println(function.apply("<<><><<"));
    System.out.println(function.apply(">>><<<"));
    System.out.println(function.apply(">>>"));
    System.out.println(function.apply("<<<"));
    System.out.println(function.apply(">><><>>"));
}
Шон Уайлд
источник
Вы можете изменить , .replaceAllчтобы .replaceи удалить скобки вокруг , (c+"")чтобы сохранить 5 байт.
Кевин Круйссен,
@KevinCruijssen Не может быть около 5 байтов, хахах.
Шон Уайлд,
При использовании правильного языка игры в гольф 5 байтов - это разница между 5-м и 2-м местом. С Java это разница между последним местом и последним местом.
Шон Уайлд,
Java почти всегда будет в последнюю очередь сталкиваться с проблемами в коде, но причина, по которой мы публикуем ответы на Java для начала, заключается в том, чтобы написать ее как можно короче. Я лично уже счастлив, если мой Java-код переходит от 500 до 499 в байтах. ; P
Кевин Круйссен
Мы в основном игнорируем всех конкурентов и просто соревнуемся с Java или C # и т. Д.
Shaun Wild
4

Желе , 27 14 12 байт

Порт @Martin Enders CJam-решение
-2 байта благодаря @Dennis

żJ0;µFṣ”<Uj”<

Проверьте это в TryItOnline

Как?

żJ0;Fṣ”<Uj”< - main link takes an argument, the string, e.g. ><>
 J           - range(length(input)), e.g. [1,2,3]
  0          - literal 0
   ;         - concatenate, e.g. [0,1,2,3]
ż            - zip with input, e.g. [[0],">1","<2",">3"]
    F        - flatten, list, e.g. "0>1<2>3"
      ”<  ”< - the character '<'
     ṣ       - split, e.g. ["0>1","2>3"]
        U    - upend (reverse) (implicit vectorization), e.g. ["1>0","3>2"]
         j   - join, e.g. "1>0<3>2"

Предыдущий метод был интересен математически, но не настолько, чтобы играть в гольф ...

=”>U
LR!×ÇĖP€S‘
L‘ḶŒ!ị@ÇðżF

При этом используется факторная базовая система, чтобы найти индекс перестановок [0, N], который будет удовлетворять уравнению.

Джонатан Аллан
источник
1
Uвекторизация, так что вам не нужно . żJ0;сохраняет еще один байт.
Деннис
4

Clojure, 152 132 126 байт

(defn f[s](loop[l 0 h(count s)[c & r]s a""](if c(case c\<(recur(inc l)h r(str a l c))(recur l(dec h)r(str a h c)))(str a l))))

Сохранено значительное количество байтов за счет устранения как можно большего количества пробелов. Я понял, что пробел не нужен, чтобы отделить скобки от другого символа.

В основном порт Clojure ответа @ Scepheo. Работает одинаково.

Эти recurзвонки убийцы! Я полагаю, я мог бы использовать атомы, чтобы очистить его. Эти swap!вызовы , необходимые для использования атомов добавляются к графе: /

Спасибо @amalloy за то, что сэкономили мне несколько байтов.

Ungolfed:

(defn comp-chain [chain-str]
  (loop [l 0 ; Lowest number
         h (count chain-str) ; Highest number
         [c & cr] chain-str ; Deconstruct the remaining list
         a ""] ; Accumulator
    (if c ; If there's any <>'s left
      (if (= c \<) ; If current char is a <...
        (recur (inc l) h cr (str a l c)) ; Add l to a, and inc l
        (recur l (dec h) cr (str a h c))) ; Add h to a, and dec h
      (str a l)))) ; Add on the remaining lowest number, and return
Carcigenicate
источник
Добро пожаловать на сайт!
DJMcMayhem
@DJMcMayhem Спасибо. Надеюсь, в следующий раз я смогу найти собственное решение, а не просто перенести другой ответ.
Carcigenicate
Вы можете сохранить еще два пробела в loopпривязке, до sи после a. Кроме того, можно бриться немного, заменив ifдерево с case: (case c \< (recur ...) nil (str ...) (recur ...)). И, конечно, crможет быть более коротким именем.
Амаллой
@amalloy Хорошие очки, спасибо. Я буду обновлять, когда я получаю на моем ноутбуке.
Carcigenicate
3

Haskell, 162 байта

import Data.List
(a:b)%(c:d)=show c++a:b%d
_%[x]=show x
f l=map(l%).filter(l#)$permutations[0..length l]
(e:f)#(x:y:z)=(e!x)y&&f#(y:z)
_#_=0<1
'>'!x=(>)x
_!x=(<)x

Это чертовски долго.

ThreeFx
источник
3

Perl (107 + 1 для -p) 108

for$c(split''){$s.=$i++.$c;}
for$b(split'<',$s.$i){$h[$j]=join'>',reverse split'>',$b;$j++;}
$_=join'<',@h;

Алгоритм, украденный из ответа Мартина Эндера

Райли
источник
2

Рубин, 135 байт

g=gets
puts g.nil?? 0:[*0..s=g.size].permutation.map{|a|a.zip(g.chars)*""if s.times.map{|i|eval"%s"*3%[a[i],g[i],a[i+1]]}.all?}.compact

Примечание: сложность по времени велика (O (n!)).

cia_rana
источник
2

Python 2, 176 172 байта

Он не очень короткий по сравнению с другими, но я рад, что решил это так быстро.

from itertools import*
def f(s):
 for p in permutations(range(len(s)+1)):
    n=list(s);p=list(p);t=[p.pop()]+list(chain(*zip(n,p)));r="".join(map(str,t))
    if eval(r):return r

Попробуйте онлайн

Ungolfed:

from itertools import*
def f(s):
    n=list(s);R=range(len(s)+1)
    for p in permutations(R):
        p=list(p)
        r=[p.pop()]
        t=n+p
        t[::2]=n
        t[1::2]=p
        r="".join(map(str,r+t))
        if eval(r):return r

Попробуйте онлайн

mbomb007
источник
чересстрочная часть может быть намного корочеzip
Maltysen
@Maltysen Не на тонну короче, потому что списки не имеют одинаковую длину (я все еще должен pop), но это немного короче. Если бы N<10я мог сделать стренификацию короче.
mbomb007
1

PHP, 190 байт

случайный случайный выбор, пока не найдется правильное решение

$x=range(0,$l=strlen($q=$argv[1]));while(!$b){$b=1;$t="";shuffle($x);for($i=0;$i<$l;){$t.=$x[$i].$q[$i];if(($q[$i]==">"&$x[$i]<$x[$i+1])|($q[$i]=="<"&$x[$i]>$x[1+$i++]))$b=0;}}echo$t.$x[$i];

381 байт получает все решения и выбирает одно

<?php $d=range(0,strlen($q=$argv[1]));echo $q."\n";$e=[];function f($t=""){global$e,$d,$q;foreach($d as$z){preg_match_all("#\d+#",$t,$y);if(in_array($z,$y[0]))continue;$p=preg_match_all("#[<>]#",$t);$g="";if(preg_match("#\d+$#",$t,$x)){if(($q[$p]==">"&$x[0]<$z)|($q[$p]=="<"&$x[0]>$z))continue;$g=$q[$p];}strlen($q)==$p+1|!$q?$e[]=$t.$g.$z:f($t.$g.$z);}}f();echo$e[array_rand($e)];
Йорг Хюльсерманн
источник