Сделать конвертер числового списка

20

Не ненавидите, когда хотите скопировать и вставить список чисел (вектор, массив ...) из одной программы в другую, но формат, в котором у вас есть числа, не соответствует формату, в котором вы нуждаетесь ?

Например, в MATLAB у вас может быть список, разделенный пробелами, например:

[1 2 3 4 5]    (you can also have it comma separated, but that's not the point)

В Python вам нужно будет ввести запятые, чтобы сделать этот список допустимым, поэтому вам придется преобразовать его в

[1, 2, 3, 4, 5]

чтобы это работало. В C ++ вы можете захотеть что-то вроде:

{16,2,77,29}

и так далее.

Чтобы упростить жизнь каждого, давайте создадим конвертер списков, который берет список в любом формате * и выводит список в другом указанном формате.

Допустимые скобки:

[list]
{list}
(list)
<list>
list      (no surrounding brackets)

Допустимые разделители:

a,b,c
a;b;c
a b c
a,  b,  c       <-- Several spaces. Must only be supported as input.
a;     b; c     <-- Several spaces. Must only be supported as input.
a   b   c       <-- Several spaces. Must only be supported as input. 

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

В дополнение к списку ввода будет строка (или два символа), определяющая формат вывода. Строка формата первой будет типом открывающей скобки (только), [, (, <, {или (последний из которых является единым пространство используется , когда нет окружающей скобки). Кронштейн типа будет сопровождаться типа разделителем, ,, ;или (последний из которых является один пробел). Два символа входного формата должны восприниматься как один аргумент (строка или два последовательных символа) в порядке, описанном выше.

Некоторые примеры форматных строк:

[,    <-- Output format:   [a,b,c]
{;    <-- Output format:   {a;b;c}
      <-- Two spaces, output list has format:   a b c   

Правила:

  • Выход не может иметь начальные пробелы
  • Вывод может иметь завершающие пробелы и перевод строки
    • На выходе должен быть только список чисел, а не ans =аналогичный
  • Входными данными будут список целых или десятичных чисел (как положительных, так и отрицательных (и ноль)), а также строка из двух символов
    • Если входные данные состоят только из целых чисел, список вывода должен содержать только целые числа. Если входной список состоит из целых и десятичных чисел, все выходные числа могут быть десятичными числами. (Необязательно хранить целые числа как целые числа)
    • Максимальное количество цифр после запятой, которое должно поддерживаться, равно 3.
    • На вход будет два аргумента. Т.е. числа находятся в одном аргументе, а строка формата - это единственный аргумент.
  • Код может быть программой или функцией
  • Ввод может быть аргумент функции или STDIN

Несколько примеров:

1 2 3 4
[,
[1,2,3,4]

<1;  2;  3>
 ;    <-- Space + semicolon
1;2;3
not valid:  1.000;2.000;3.000   (Input is only integers => Output must be integers)

{-1.3, 3.4, 4, 5.55555555}
[,
[-1.300,3.400,4.000,5.556]  (5.555 is also valid. Rounding is optional)
also valid: [-1.3,3.4,4,5.55555555]

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


Leaderboard

Фрагмент стека в нижней части этого поста создает каталог из ответов а) в виде списка кратчайшего решения для каждого языка и б) в качестве общей таблицы лидеров.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

## Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

## Ruby, <s>104</s> <s>101</s> 96 bytes

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

## Perl, 43 + 2 (-p flag) = 45 bytes

Вы также можете сделать имя языка ссылкой, которая будет отображаться во фрагменте кода:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Стьюи Гриффин
источник
Разрешено ли использовать пробелы в конце и в начале?
переиздание
@overactor, см. первые два правила. Лидирующий пробел не в порядке, трейлинг в порядке.
Стьюи Гриффин
Можем ли мы принять входные данные в обратном порядке? (разделители первые, список второй)
Мартин Эндер
@ MartinBüttner, да. Не указано, что это должен быть список первым, так что вы можете выбрать.
Стьюи Гриффин
J использует _для обозначения отрицательных элементов. :(
Zgarb

Ответы:

1

CJam, 27 байт

l)l_5ms`-SerS%*\S-_o_'(#(f-

Попробуй это здесь.

объяснение

l      e# Read the format string.
)      e# Extract the separator.
l_     e# Read the list.
5ms`   e# Get a string that contains -.0123456789.
-      e# Get the characters in the list that are not in the string.
Ser    e# Replace those characters with spaces.
S%     e# Split by those characters, with duplicates removed.
*      e# Join with the separator.
\S-    e# Remove spaces (if any) from the left bracket.
_o     e# Output a copy of that character before the stack.
_'(#   e# Find '( in the left bracket string.
(      e# Get -1 if '( is the first character, and -2 if it doesn't exist.
f-     e# Subtract the number from every character in the left bracket string,
          making a right bracket.
jimmy23013
источник
8

JavaScript (ES6), 75 82

Как анонимная функция

Редактирование: 2 байта сохранены thx @ user81655 (и еще 5, просто просматривая его)

(l,[a,b])=>a.trim()+l.match(/[-\d.]+/g).join(b)+']})> '['[{(< '.indexOf(a)]

Тестовый фрагмент

F=(l,[a,b])=>a.trim()+l.match(/[-\d.]+/g).join(b)+']})> '['[{(< '.indexOf(a)]

// Test
console.log=x=>O.innerHTML+=x+'\n'
// default test suite
t=[['1 2 3 4','[,'],['<1;  2;  3>',' ;'],['{-1.3, 3.4, 4, 5.55555555}','[,']]
t.forEach(t=>console.log(t[0]+' *'+t[1]+'* '+F(t[0],t[1])))
function test() { console.log(P1.value+' *'+P2.value+'* '+F(P1.value,P2.value)) }
#P1 { width: 10em }
#P2 { width: 2em }
P1<input id=P1>
P2<input id=P2>
<button onclick="test()">-></button>
<pre id=O></pre>

edc65
источник
6

CJam, 35 34 байта

l(S-l"{[<(,}]>);":BSerS%@*1$B5/~er

Проверьте это здесь.

Ожидается формат в первой строке и список во второй.

объяснение

l   e# Read the format line.
(   e# Pull off the first character, which is the opening bracket.
S-  e# Set complement with a space, which leaves brackets unchanged and turns a space
    e# into an empty string.
l   e# Read the list.
"{[<(,}]>);":B
    e# Push this string which contains all the characters in the list we want to ignore.
Ser e# Replace each occurrence of one of them with a space.
S%  e# Split the string around runs of spaces, to get the numbers.
@   e# Pull up the the delimiter string.
*   e# Join the numbers in the list with that character.
1$  e# Copy the opening bracket (which may be an empty string).
B5/ e# Push B again and split it into chunks of 5: ["{[<(," "}]>);"]
~   e# Unwrap the array to leave both chunks on the stack.
er  e# Use them for transliteration, to turn the opening bracket into a closing one.
Мартин Эндер
источник
5

Pyth, 33 байта

rjjezrXwJ"<>[]  {}(),;"d7@c6JChz6

Попробуйте онлайн: демонстрация или тестовый набор

Объяснение:

J"<>[]  {}(),;"  assign this string to J

rjjezrXwJd7@c6JChz6   implicit: z = first input string, e.g. "[;"
       w              read another string from input (the list of numbers)
      X Jd            replace every char of ^ that appears in J with a space
     r    7           parse ^ (the string of numbers and spaces) into a list
  jez                 put z[1] (the separator symbol) between the numbers
            c6J       split J into 6 pieces ["<>", "[]", "  ", "{}", "()", ",;"]
               Chz    ASCII-value of z[0] (opening bracket symbol)
           @          take the correspondent (mod 6) brackets from the list
 j                    and put the numbers between these brackets
r                 7   remove leading and trailing spaces
Jakube
источник
Можете ли вы объяснить, как это работает?
Шелваку
1
@Shel Вот ты где.
Якуб
5

PowerShell, 108 100 95 85 байт

$i,$z=$args;($z[0]+($i-split'[^\d.-]+'-ne''-join$z[1])+' }) >]'[($z[0]-32)%6]).Trim()

(см. историю изменений для предыдущих версий)

Гольф еще 15 байтов, удаляя $bи $sпеременные и меняя парены на внутренней строке.

Он принимает входные данные в виде двух строк и сохраняет их в, $iа $zзатем мы создаем новую выходную строку. Внутренние парены -splitс $iрегулярным выражением для выбора только числовых цифр, а затем -joinснова вместе с запрошенным разделителем. Мы объединяем это с первым символом ввода разделителя (например, [) и закрываем его индексированием в строку, основанную на значении ASCII первого символа и некоторой хитрости формулировки. Внешний .Trim()удаляет любые ведущие или конечные пробелы.

AdmBorkBork
источник
Я думаю, что вы могли бы заменить выражение закрывающей скобки "]})>"["[{(< ".IndexOf($b[0])]на что-то вроде ' }) >]'[($b[0]-32)%6]. Это ($b[0]-32)%6дает вам 0,2,4,5,1возможность открывать символы в скобках, которые вы можете использовать для индексации в строке закрывающей скобки ' }) >]'. Там может быть более короткая «формула», но это кажется достаточно хорошим.
Данко Дурбич
@ DankoDurbić Отлично! Я пытался придумать какую-то математику, чтобы выбрать правильный выходной символ на основе значений ASCII, но я не смог найти правильную формулу. Меня постоянно сбивали с толку, когда я ()находился рядом друг с другом, но в других скобках есть символ между ними, поэтому я занялся индексированием. Благодарность!
AdmBorkBork
Использование String.Replace()вместо -replaceоператора даст вам еще 2 байта (не нужно экранировать или определять класс символов с помощью [])
Mathias R. Jessen
@ MathiasR.Jessen Если я что-то здесь не упустил, .Replace('[]{}()<>;,',' ')он не будет ловить отдельные символы, а вместо этого попытается сопоставить символическое целое, которого не существует. Нам нужно использовать Regex.Replace , который включает [regex]::вызов .NET и вместо этого удлиняет код.
AdmBorkBork
@ TessellatingHeckler Спасибо! Я использовал другой байт -ne''вместо |?{$_}.
AdmBorkBork
4

Python 2, 96 байт

import re
lambda(a,(b,c)):(b+c.join(re.findall('[-\d\.]+',a))+'])>} '['[(<{ '.index(b)]).strip()

Звоните как:

f(('{-1.3, 3.4, ,4, 5.55555555}','[,'))

Выход:

[-1.3,3.4,4,5.55555555]
TFeld
источник
2

JavaScript (ES6), 82 92 116 92 байта

(a,b)=>(c=a.match(/-?\d+(\.\d+)?/g).join(b[1]),d=b[0],d<"'"?c:d+c+"]}>)"["[{<(".indexOf(d)])

Анонимная функция, запустите ее так

((a,b)=>(c=a.match(/-?\d+(\.\d+)?/g).join(b[1]),d=b[0],d<"'"?c:d+c+"]}>)"["[{<(".indexOf(d)]))("{1;  2;3;   4}","<;")

Это, вероятно, может быть дальше в гольф ..

Ungolfed

(a,b)=>(                             // "{1;  2;3;   4}", "<;"
    c=a.match(/-?\d+(\.\d+)?/g)      // regex to match decimals
    .join(b[1]),                     // c -> "1;2;3;4"
    d=b[0],                          // d -> "<"
    d<"'" ?                          // if d is smaller than ' then ...
        c :                          // return just "1;2;3;4"
        d + c +                      // "<" + "1;2;3;4" + ...
        "]}>)" [ "[{<(".indexOf(d) ] // "]}>)"[2] -> ">"
)
Bassdrop Cumberwubwubwub
источник
Я думаю, что вы должны принять как строку, а не список.
переиздание
Совершенно неправильно понял это The input will be a list of integer or decimal numbers (both positive and negative (and zero)), and a string of two characters. Исправлено, спасибо
Bassdrop Cumberwubwubwub
2

Mathematica, 108 байт

Mathematica обычно неуклюжа со строковыми входами, если строка не предназначена для интерпретации как текст.

c=Characters;t_~f~p_:=({b,s}=c@p;b<>Riffle[StringCases[t,NumberString],s]<>(b/.Thread[c@"[ {<(" -> c@"] }>)"]))

объяснение

StringCases[t,NumberString]возвращает список числовых строк.

Riffleвставляет разделители между числами.

/.Thread[c@"[ {<(" -> c@"] }>)"]) заменяет левую «скобку» на правую скобку.

<>это инфиксная форма StringJoin. Склеивает подстроки.

DavidC
источник
2

Matlab, 85 байт

@(s,x)[x(1) strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)) x(1)+(x(1)~=32)+(x(1)~=40)]

Пример использования:

>> @(s,x)[x(1) strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)) x(1)+(x(1)~=32)+(x(1)~=40)]
ans = 
    @(s,x)[x(1),strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)),x(1)+(x(1)~=32)+(x(1)~=40)]

>> ans('1 2.4 -3 -444.555 5', '[,')
ans =
[1,2.4,-3,-444.555,5]
Луис Мендо
источник
1

Юлия, 95 байт

f(l,s)=(x=s[1]<33?"":s[1:1])*join(matchall(r"[\d.-]+",l),s[2])*string(x>""?s[1]+(s[1]<41?1:2):x)

Это функция, fкоторая принимает две строки и возвращает строку.

Ungolfed:

function f{T<:AbstractString}(l::T, s::T)
    # Extract the numbers from the input list
    n = matchall(r"[\d.-]+", l)

    # Join them back into a string separated by given separator
    j = join(n, s[2])

    # Set the opening bracket type as the empty string unless
    # the given bracket type is not a space
    x = s[1] < 33 ? "" : s[1:1]

    # Get the closing bracket type by adding 1 or 2 to the ASCII
    # value of the opening bracket unless it's an empty string
    c = string(x > "" ? s[1] + (s[1] < 41 ? 1 : 2) : x)

    # Put it all together and return
    return x * j * c
end
Алекс А.
источник
1

Bash + GNU Utilities, 90

b=${2:0:1}
echo $b`sed "s/[][{}()<>]//g;s/[,; ]\+/${2:1}/g"<<<"$1"``tr '[{(<' ']})>'<<<$b`
Цифровая травма
источник