Эликсир Array Синтаксический сахар

17

В Elixir (связанные) списки имеют формат, в [head | tail]котором head может быть любым, а tail - списком остальной части списка, и []- пустой список - единственное исключение из этого.

Списки также могут быть написаны как [1, 2, 3]что эквивалентно[1 | [2 | [3 | []]]]

Ваша задача - преобразовать список, как описано. Входными данными всегда будет действительный список (в Elixir), содержащий только числа, соответствующие регулярному выражению \[(\d+(, ?\d+)*)?\]. Вы можете взять ввод с (один пробел после каждой запятой) или без пробелов. Вывод может быть с (один пробел до и после каждого |) или без пробелов.

Для входов с ведущими нулями вы можете выводить либо без нулей, либо с помощью.

Входные данные должны восприниматься как строка (если пишется функция), как и выходные данные.

Примеры

[] -> []
[5] -> [5 | []]
[1, 7] -> [1 | [7 | []]]
[4, 4, 4] -> [4 | [4 | [4 | []]]]
[10, 333] -> [10 | [333 | []]]

связанный , а не дубликат, так как это отчасти подразумевает добавление режима ]до конца. Кроме того, ответ на Haskell здесь сильно отличается от ответа на этот вопрос.

Okx
источник
5
-1 от меня. Громоздкие форматы ввода-вывода не приветствуются. Если вход представляет собой список, давайте возьмем его в качестве списка, вместо того, чтобы 90% нашего кода просто анализировали ввод
Jo King
2
Должны ли мы поддерживать ведущие 0? Они соответствуют регулярному выражению.
Джо Кинг
2
Возможный дубликат синтаксиса без сахара
NoOneIsHere
5
@ JoKing Я бы сказал, что в данном случае сама задача заключается в преобразовании между двумя конкретными форматами, поэтому анализ входных данных является основной частью задачи, а не чем-то дополнительным к ней добавляемой. PS Я только сейчас понял, что на самом деле твой ник xD
Лев
2
@MuhammadSalman: задача помечена как «синтаксический анализ», поэтому преобразование из / в строку является существенной ее частью с намерением.
Ними

Ответы:

9

Haskell, 50 байтов

f.read
f(a:b)='[':show(a+0)++'|':f b++"]"
f _="[]"

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

Модуль +0проверки типа Haskell знает, что мы имеем дело со списками чисел, поэтому readпроанализируем входную строку для нас.

Ними
источник
1
+1, я люблю трюк +0!
Б. Мехта
4

Retina , 39 33 32 20 байт

\b]
,]
+`,(.*)
|[$1]

Сохранено 13 байтов благодаря H.PWiz, ovs, ASCII-only и Neil.
Попробуйте онлайн!

объяснение

\b]
,]

Если у нас нет пустого списка, добавьте запятую.

+`,(.*)
|[$1]

Пока есть запятые, оберните вещи |[ thing ].


источник
@ovs 24?
Только для ASCII
также 24?
Только для ASCII
@ Только для ASCII Вы можете сохранить еще 4 байта, заменив их \b]на ,]. (В противном случае я независимо обнаружил одно и то же решение.)
Нейл
О, это верно. Я \bпо какой-то причине забыл что-то> _> 20 байт @Mnemonic
только для ASCII
4

Perl 5 -pl , 31 28 байт

s/\d\K]/,]/;$\=']'x s/,/|[/g

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

Как?

-p                    # (command line) Implicit input/output via $_ and $\
s/\d\K]/,]/;          # insert a comma at the end if the list is not empty
$\=']'x s/,/|[/g      # At the end of the run, output as many ']' as there are
                      # commas in the input.  Replace the commas with "|["
Xcali
источник
3

Эликсир , 111 85 байт

f=fn[h|t],f->"[#{h}|#{f.(t,f)}]"
[],_->"[]"
h,f->f.(elem(Code.eval_string(h),0),f)end

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

Я никогда не использовал Эликсир раньше. Определяет функцию, которая принимает строку и ссылку на себя и возвращает строку.

Джо Кинг
источник
3

Цейлон , 113 байт

String p(String s)=>s.split(" ,[]".contains).select((x)=>!x.empty).reversed.fold("[]")((t,h)=>"[``h`` | ``t``]");

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

Вот это выписано:

// define a function p mapping Strings to Strings.
String p(String s) =>
    // we split the string at all characters which are brackets, comma or space.
    s.split(" ,[]".contains)    // → {String+}, e.g.  { "", "1", "7", "" }
    // That iterable contains empty strings, so let's remove them.
    // Using `select` instead of `filter` makes the result a sequential instead of
    // an Iterable.
     .select((x)=>!x.empty)    // → [String*], e.g.   [1, 7]
    // now invert the order.
    // (This needs a Sequential (or at least a List) instead of an Iterable.)
     .reversed                 // → [String*], e.g.   [7, 1]
    // Now iterate over the list, starting with "[]", and apply a function
    // to each element with the intermediate result.
     .fold("[]")                       // → String(String(String, String))
    //    This function takes the intermediate result `t` (for tail) and an element
    //    `h` (for head), and puts them together into brackets, with a " | " in the
    //    middle. This uses String interpolation, I could have used `"+` and `+"`
    //    instead for the same length.
          ((t,h)=>"[``h`` | ``t``]");  // → String

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

Как отметил ovs в (теперь удаленном) комментарии: если выбрать вариант «без пробелов» для ввода и вывода, указанных в вопросе, можно сохранить еще 3 байта (очевидные с пробелами в них).

Если нам не нужно анализировать входные данные, а просто можно получить последовательность в качестве входных данных, она становится намного короче (69 байт).

String p(Object[]s)=>s.reversed.fold("[]")((t,h)=>"[``h`` | ``t``]");

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

Пауло Эберманн
источник
2

SNOBOL4 (CSNOBOL4) , 114 байт

	I =INPUT
S	N =N + 1	
	I SPAN(1234567890) . L REM . I	:F(O)
	O =O '[' L ' | '	:(S)
O	OUTPUT =O '[' DUPL(']',N)
END

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

	I =INPUT				;* read input
S	N =N + 1				;* counter for number of elements (including empty list)
	I SPAN(1234567890) . L REM . I	:F(O)	;* get value matching \d until none left
	O =O '[' L ' | '	:(S)		;* build output string
O	OUTPUT =O '[' DUPL(']',N)		;* print O concatenated with a '[' and N copies of ']'
END
Giuseppe
источник
2

Stax , 19 байт

É▲²:WlÖ└%ï╪☺╒▓"We↨Φ

Запустите и отладьте его

Мой первый пост Stax, так что, вероятно, не оптимально.

Распаковано и прокомментировано:

U,                      Put -1 under input
  {                     Block
   i                      Push loop index, needed later
    '[a$'|++              Wrap the element in "[...|"
            m           Map
             '[+        Add another "["
                s2+     Get the latest loop index + 2
                   ']*+ Add that many "]"

Запустите и отладьте этот

Wastl
источник
2

Befunge-98 (PyFunge) , 22 21 байт

'[,1;@j,]';#$&." |",,

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

Если бы не было странных ограничений на вывод, мы могли бы сделать это в 18:

'[,1;@j,]';#$&.'|,

Забавный факт, технически это программа, которая ничего не делает на Python.

Джо Кинг
источник
2

R , 84 71 69 байт

function(x){while(x<(x=sub('(,|\\d\\K(?=]))(.+)','|[\\2]',x,,T)))1;x}

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

  • -15 байт благодаря @KirillL.
digEmAll
источник
1
71 байт с одной заменой на основе моего ответа Ruby.
Кирилл Л.
@KirillL. : спасибо, я был уверен, что для этого есть более короткое регулярное выражение, но я всегда путаюсь с обходными путями: D
digEmAll
-2 больше , я полностью забыл о более коротком \Kвзгляде назад
Кирилл Л.
1

Желе , 18 байт

ŒVµ⁾[]jj⁾|[ṫ3;”]ṁ$

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

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

Как?

ŒVµ⁾[]jj⁾|[ṫ3;”]ṁ$ - Main link: list of characters  e.g. "[10,333]"
ŒV                 - evaluate as Python code              [10,333]
  µ                - start a new monadic chain, call that X
   ⁾[]             - list of characters                   ['[',']']
      j            - join with X                          ['[',10,333,']']
        ⁾|[        - list of characters                   ['|','[']
       j           - join                                 ['[','|','[',10,'|','[',333,'|','[',']']
           ṫ3      - tail from index three                ['[',10,'|','[',333,'|','[',']']
                 $ - last two links as a monad (f(X)):
              ”]   -   character                          ']'
                ṁ  -   mould like X                       [']',']'] (here 2 because X is 2 long)
             ;     - concatenate                          ['[',10,'|','[',333,'|','[',']',']',']']
                   - implicit (and smashing) print        [10|[333|[]]]
Джонатан Аллан
источник
1

Java 10, 107 байт

s->{var r="[]";for(var i:s.replaceAll("[\\[\\]]","").split(","))r="["+i+"|"+r+"]";return s.length()<3?s:r;}

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

Объяснение:

s->{                       // Method with String as both parameter and return-type
  var r="[]";              //  Result-String, starting at "[]"
  for(var i:s.replaceAll("[\\[\\]]","") 
                           //  Removing trailing "[" and leading "]"
             .split(","))  //  Loop over the items
    r="["+i+"|"+r+"]";     //   Create the result-String `r`
  return s.length()<3?     //  If the input was "[]"
          s                //   Return the input as result
         :                 //  Else:
          r;}              //   Return `r` as result
Кевин Круйссен
источник
1

Стандартный ML , 71 байт

fun p[_]="]|[]]"|p(#","::r)="|["^p r^"]"|p(d::r)=str d^p r;p o explode;

Попробуйте онлайн! Использует формат без пробелов. Например, it "[10,333,4]"урожайность"[10|[333|[4]|[]]]]" .

ungolfed

fun p [_]       = "]|[]]"          (* if there is only one char left we are at the end *)
  | p (#","::r) = "|[" ^ p r ^ "]" (* a ',' in the input is replaced by "|[" and an closing "]" is added to the end *)
  | p (d::r)    = str d ^ p r      (* all other chars (the digits and the initial '[') are converted to a string and concatenated to recursive result *)

val f = p o explode  (* convert string into list of chars and apply function p *)

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

Laikoni
источник
1

R , 140 136 байт

Вниз на 4 байта в соответствии с рекомендациями Джузеппе.

function(l,x=unlist(strsplit(substr(l,2,nchar(l)-1),", ")))paste(c("[",paste0(c(x,"]"),collapse=" | ["),rep("]",length(x))),collapse="")

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

Jayce
источник
substrкороче и первым paste0можно pasteполучить это до 136 байтов.
Джузеппе
1
Используя eval, parseи subвместо unlist, strsplitи substr, я также управлял только 136 байтами (я думал, что это могло бы быть короче, но это не было)
Джузеппе
@Giuseppe Спасибо за -4 байта! Я хотел бы, чтобы у нас было что-то короче. Может быть, рекурсивное решение?
JayCe
1

R , 108 байт

function(l)Reduce(function(x,y)paste0("[",x,"|",y,"]"),eval(parse(t=sub("]",")",sub("\\[","c(",l)))),"[]",T)

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

Потребовался почти год, чтобы найти лучшее решение R, чем предыдущее ... должен был знать, Reduceбудет ответ! Выходы без пробелов, ввод может быть с пробелами или без них.

Giuseppe
источник
0

sed + -E, 46 байт

:
s/\[([0-9]+)(, ?([^]]*)|())\]/[\1 | [\3]]/
t

Довольно простой подход. Вторая строка берет [\d+, ...]и меняет его на [\d | [...]]. Третья строка переходит обратно на первую строку, если замена прошла успешно. Замена повторяется до тех пор, пока не произойдет сбой, а затем программа завершится. Запуск с sed -E -f filename.sedпередачей ввода через стандартный ввод.

Сильвио Майоло
источник
0

Красный , 110 байт

func[s][if s ="[]"[return s]replace append/dup replace/all b: copy s",""|[""]"(length? b)- length? s"]""|[]]"]

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

Объяснение версии без гольфа:

f: func[s][                      
    if s = "[]" [return s]                    ; if the list is empty, return it    
    b: copy s                                 ; save a copy of the input in b 
    replace/all b "," "|["                    ; replace every "," with "|["  
    append/dup b "]" (length? b) - length? s  ; append as many "]" as there were ","
    replace b "]" "|[]]"                      ; replace the first "]" with "|[]]"     
]                                             ; the last value is returned implicitly

Красный настолько легко читается, что я сомневаюсь, что мне нужно было добавить вышеупомянутые комментарии :)

Гален Иванов
источник