Синтаксичний цукор Elixir Array


17

У Elixir (пов'язані) списки є у форматі, [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 | []]]

пов'язані , а не дублікат, оскільки це частково передбачає додавання режиму ]до кінця. Крім того, відповідь Хаскелла тут зовсім інша, ніж відповідь.


5
-1 від мене. Обтяжливі формати вводу-виводу не перешкоджають. Якщо вхід є списком, давайте сприймемо його як список, а не 90% нашого коду просто розбирає вхід
Джо Кінг

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

Сітківка , 39 33 32 20 байт

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

Збережено 13 байт завдяки H.PWiz, ovs, лише ASCII та Нілу.
Спробуйте в Інтернеті!

Пояснення

\b]
,]

Якщо у нас немає порожнього списку, додайте коду в кінці.

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

Поки є коми, загортайте речі |[ thing ].




@ Лише для 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 "|["


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

2

Стакс , 19 байт

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

Запустіть і налагоджуйте його

Мій перший пост у Стаксі, так що, мабуть, не оптимально.

Розпакували та прокоментували:

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 "]"

Запустити та налагодити цей





2

R , 84 71 69 байт

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

Спробуйте в Інтернеті!

  • -15 байт завдяки @KirillL.

1
71 байт з однією заміною на основі моєї відповіді Рубі.
Кирило Л.

@KirillL. : дякую, я був впевнений, що для цього є коротший регулярний вираз, але я завжди псуюся з lookarounds: 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]|[]]]]".

неозорий

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 *)

Спробуйте в Інтернеті!


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="")

Спробуйте в Інтернеті!


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це буде відповідь! Виходи без пробілів, введення може бути з пробілами або без.




0

sed + -E, 46 байт

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

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


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

Червоний настільки легко читабельний, що я сумніваюся, що мені потрібно було додати вищезазначені коментарі :)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.