Получив строку, состоящую из печатных символов ASCII, создайте вывод, состоящий из его уникальных символов в исходном порядке . Другими словами, выходные данные совпадают с входными данными за исключением того, что символ удаляется, если он появился ранее.
Никакие встроенные модули для поиска уникальных элементов в массиве не могут быть использованы (например, в MATLAB есть unique
функция, которая делает это). Идея состоит в том, чтобы сделать это вручную.
Более подробная информация:
- Любые функции или программы разрешены.
- Ввод и вывод могут быть в форме аргументов функции, stdin / stdout (даже для функций) или их комбинации.
- Если используются stdin или stdout, под строкой понимается только последовательность символов . Если используются аргументы функции, последовательность символов может быть заключена в кавычки или эквивалентные символы, которые предпочитаемый язык программирования использует для определения строк.
- Вывод должен быть строкой, содержащей только уникальные символы ввода. Так что никаких дополнительных разрывов строк, пробелов и т. Д. Единственное исключение: если вывод отображается в stdout, большинство отображающих функций добавляют трейлинг
\n
(чтобы отделить строку от того, что будет дальше). Таким образом, один трейлинг\n
приемлем в stdout . - Если возможно, опубликуйте ссылку на онлайн- интерпретатор / компилятор, чтобы другие могли попробовать ваш код.
Это код гольф , поэтому выигрывает самый короткий код в байтах.
Несколько примеров , предполагающих stdin и stdout:
Строка ввода:
Type unique chars!
Выходная строка:
Type uniqchars!
Строка ввода
"I think it's dark and it looks like rain", you said
Выходная строка
"I think'sdarloe,yu
Строка ввода
3.1415926535897932384626433832795
Выходная строка
3.14592687
Ответы:
GolfScript, 2 байта
или, альтернативно:
Я опубликовал это некоторое время назад в Совете по игре в гольф в теме GolfScript . Он работает путем дублирования входной строки (которая автоматически помещается в стек интерпретатором GolfScript и которая в большинстве случаев ведет себя как массив символов), а затем беря ее пересечение set (
&
) или union (|
). Применение оператора set к массиву (или строке) сворачивает любые дубликаты, но сохраняет порядок элементов.источник
CJam, 3 байта
По умолчанию или ввода с пустым списком. Операции над множествами CJam сохраняют порядок элементов.
Попробуйте онлайн
источник
C # 6, 18 + 67 = 85 байт
Требуется это
using
утверждение:Фактический метод:
Этот метод экономит некоторые символы, определяя функцию как лямбду , которая поддерживается в C # 6. Вот как это будет выглядеть в C # pre-6 (но не golphed):
Как это работает: я вызываю
Where
метод в строке с лямбда-выражением с двумя аргументами:x
представляющий текущий элемент,i
представляющий индекс этого элемента.IndexOf
всегда возвращает первый индекс переданного ему символа, поэтому, еслиi
он не равен первому индексуx
, это дублирующий символ и не должен быть включен.источник
static void Main
т. Д.).Сетчатка , 14 байт
Каждая строка должна идти в своем отдельном файле, или вы можете использовать
-s
флаг для чтения из одного файла.Чтобы объяснить это, мы будем использовать эту более длинную, но более простую версию:
Первая строка - это регулярное выражение для сопоставления (
+`
это строка конфигурации, которая работает до тех пор, пока не будут выполнены все замены). Регулярное выражение ищет символ (назовем его C), за которым следует ноль или более произвольных символов, а затем C. Скобки обозначают группы захвата, поэтому мы заменяем совпадение на C ($1
) и символы между ними ($2
), удаление дубликата C.Например, если входная строка была
unique
, первый запуск будет соответствоватьuniqu
, сu
иniq
как$1
и$2
, соответственно. Затем он заменит подстроку в исходном вводе наuniq
, даваяuniqe
.источник
Perl, 21 (20 байт +
-p
)Использование:
источник
$h{$&}
и используя логическую AND вместо троичного оператора:s/./!$h{$&}++&&$&/eg
1
s в выводе, но это не так! Спасибо, обновление!s/./$h{$&}++||$&/eg
(я тоже влюбился в это сначала). Позор, потому что это был бы другой сохраненный байт.Макароны 0.0.2 , 233 байта
Это полная программа, которая вводит из STDIN и выводит из STDOUT.
Завернутая версия, для эстетической ценности:
И сильно «закомментированная» и нелегальная версия (в Макаронах нет комментариев, поэтому я просто использую строковые литералы):
(Это первая настоящая макаронная программа (которая действительно что-то делает)! \ O /)
источник
JavaScript ES7,
373325 байтДовольно простой подход с использованием ES6
Set
и ES7Array.22 байта меньше, чем
indexOf
подход. Работал над несколькими тестовыми случаями.источник
for
выражения «S не нужны , и вы могли бы сделать это анонимная функция как и некоторые другие решения:s=>[for(c of Set(s))c].join``
. (Бледное обновление: не уверен на 100%, ноnew
ключевое слово кажется также ненужным.)new
привелаUncaught TypeError: Constructor Set requires 'new'
в Google Chrome.C # 6 - 18 + 46 = 64
а потом
Метод
Enumerable.Union
extension указывает, что элементы возвращаются в исходном порядке:Судя по другим ответам, операции набора, которые специально не предназначены для поиска уникальных значений, разрешены.
источник
string u(string s)=>String.Join("",s.Distinct());
но это немного дольше.Distinct()
уже, но он удален, потому чтоDistinct()
не разрешен в этой задаче, поскольку это метод, специально предназначенный для поиска уникальных значений.s => string.Concat(s.Union(s))
действительным? Это будет делегат, переданныйFunc<string, string>
в качестве аргумента.JavaScript ES6, 47 байт
Тест ниже работает на всех браузерах.
источник
<i?'':e
часть?e
находится перед текущим индексомi
, он возвращает пустую строку, тем самым избавляясь от символа. Если это первый экземпляр, он просто возвращаетсяe
и никаких изменений не производится.МАТЛАБ, 23
Выполняет «установление объединения» входной строки с собой, используя метод «stable», который не сортирует, а затем печатает.
Это работает, потому что
union
возвращает только неповторяющиеся значения после слияния. Таким образом, по сути, если выunion
используете строку с самим собой, она сначала создает строку, похожую на строкуType unique chars!Type unique chars!
, а затем удаляет все дубликаты без сортировки.Не нужно для
unique
:)источник
unique
не допускается, извините! Это в определении проблемыsetdiff
с'stable'
вариантом?disp
потому что тогда у вас есть функция, которая возвращает строку, что разрешеноintersect
с ,'stable'
чтобы достичь того же эффекта тоже. Я собирался написать это, но, учитывая этот ответ, он больше не оригинален, лол.> <> , 16 байт
> <> не имеет строк, поэтому мы используем кодовое поле. Из-за тороидальной природы> <> в цикле выполняется следующее:
Обратите внимание, что здесь используется тот факт, что входные данные содержат только печатный ASCII, поскольку это не сработало бы, если бы присутствовал ASCII 0.
источник
Луч ,
2318 байтПопробуйте онлайн!
источник
Элемент ,
221918 байтПример ввода / вывода:
hello world
->helo wrd
Это работает, просто обрабатывая строку по одному символу за раз и отслеживая, какие из них она видела раньше.
источник
Python 2, 42 байта
Использует пару анонимных функций и
reduce
.Попробуйте онлайн
источник
Python 3, 44
Создает выводимую строку
r
символ за символом, включая символc
из ввода, только если мы его еще не видели.Python 2 был бы 47, теряя 4 символа с
raw_input
и сохраняя 1 на не нуждающихся в parersprint
.источник
input
в Python 2, чтобы вы могли сделать свой байт короче.APL, 3
Это применяет объединение (∪) между каждым элементом вектора, получая итерацию, которая приводит к удалению дубликатов.
Проверьте это на tryapl.org
Старый:
При этом используется ~ (с обратными аргументами, используя ⍨), применяемый между каждым элементом аргумента. В результате для каждого элемента, если он уже есть в списке, он стирается.
источник
Perl,
5427 байтТест:
источник
print exists($h{$_})?"":$_
→$h{$_}||print
$h{$_}||=print
а использование также<>=~/./g
поможет сэкономить еще несколько!map
также улучшило бы экономию:map{$h{$_}||=print}<>=~/./g
PHP, 72 байта
84 байтаИспользует символы в качестве ключей для ассоциативного массива, затем печатает ключи. Порядок элементов массива всегда является порядком вставки.
Спасибо Исмаилу Мигелю за
str_split
предложение.источник
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));
Короче и делает то же самое.while($c=$argv[1][$i++*1])
. Это заменяет целоеforeach
. Все остальное то же самое"0"
. Попробуйте "abc0def" в качестве ввода.Pyth, 7 байт
псевдокод:
z = вход
сумма порядкового индекса в z из N над множеством z.
источник
Юлия,
4542 байтаСтарая версия:
Код строит новую строку, добавляя в нее новые символы, а затем
join
помещает их вместе в нужную строку в конце. В новой версии некоторые символы сохраняются путем итерации через понимание массива. Также сохраняет байт, используя?:
вместо||
(поскольку это устраняет необходимость в скобках вокруг назначения).Альтернативное решение, 45 байтов, с использованием рекурсии и регулярного выражения:
Юлия, 17 байт
(Альтернативная версия)
Это использует
union
в основном как заменуunique
- я не считаю это "реальным" ответом, так как я интерпретирую "не использоватьunique
", чтобы означать "не использовать единственную встроенную функцию, которая имеет эффект возврата уникального элементы».источник
Java, 78 байт
Простой цикл при проверке выходных данных для уже существующих символов. Принимает ввод как
char[]
.источник
C 96 байтов
При этом используется массив целых чисел, проиндексированный по номеру символа ASCII. Символы печатаются только в том случае, если для этого места в массиве установлено значение FALSE. После того, как каждый новый символ найден, это место в массиве устанавливается в TRUE. Это берет строку текста из стандартного ввода, завершается новой строкой. Он игнорирует не-ASCII символы.
Ungolfed:
источник
С - 58
Спасибо @hvd и @AShelly за сохранение группы символов. Было предложено несколько способов сделать его намного короче оригинала:
Как видите, модификация на месте кажется самой короткой (пока!). Тестовая программа компилируется без предупреждений, используя
gcc test.c
Спасибо за помощь. Я ценю все советы, которые даются, чтобы сократить так много!
источник
r
какint
(и опускаемint
) , чтобы сохранить несколько байт:f(s,r)char*s;{...}
. Но он ограничивает ваш код платформами,char*
размер которых совпадает с размеромint
, и, конечно, компиляторы так же снисходительны, как ваша и моя.if(x)y
наx?y:0
f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
*q
и только увеличивать,q
если символ появился раньше, что позволяет добавлять немного больше воедино:void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}
(Обратите внимание, чтоstrchr(r,*s++)<q
всегда четко определено, там нет UB, потому чтоstrchr
не может вернутьсяNULL
в этой версии.) За исключением типа возврата, это даже короче, чем версия @ AShelly.Рубин,
3024 символов(23 символа кода + 1 символ опции командной строки.)
Образец прогона:
источник
CJam, 9
Это не преобразует строку в набор, но выполняет своего рода разность наборов, чтобы определить, найден ли символ в строке. Попробуйте онлайн
Объяснение:
Другая версия, 13 байт:
Это не имеет ничего общего с сетами. Попробуйте онлайн
Объяснение:
источник
TI-BASIC, 49 байтов
Переменные уравнения редко бывают полезными, поскольку для их хранения требуется 5 байт, но
Y₁
здесь они пригодятся какX
символ строки, сохраняя 3 байта. Поскольку мы не можем добавить пустые строки в TI-BASIC, мы начинаем строку с первого символа Str1, затем перебираем оставшуюся часть строки, добавляя все символы, которые еще не встречались.источник
Matlab, 46 байт
Он использует анонимную функцию с аргументами функции в качестве входа и выхода:
(Я не мог заставить это работать в онлайн-переводчике Octave.)
Пример использования:
источник
,1
withany
.1
это дляtriu
(мне нужно убрать диагональ), а не дляany
Befunge -93, 124 байта
Проверьте это в этом онлайн-переводчике .
Это было сложнее, чем я ожидал. Завтра я опубликую более полное объяснение, если кто-то захочет, но вот обзор того, что делает мой код.
2,0
правого края и продолжая его. Это проверено, чтобы видеть, является ли текущий символ дубликатом.0,0
а счетчик цикла проверки на наличие дубликатов хранится в1,0
.0,0
увеличивается.источник
PHP,
5654Вычеркивая ответ @ fschmengler, используя
array_flip
дважды - вторая версия использует метод переменных и полагается на приведение строки к истине, отрицание ее к ложному, затем приведение ее к пустой строке в первом аргументе, чтобы сохранить пару байтов во втором. Дешевые!источник
Haskell , 29 байт
Вложенный, без строкового имени, одна строка:
Тот же счетчик, сохраненный в функции, названной
f
как объявление верхнего уровня:Обратите внимание, что есть немного обманчивая оптимизация, которую я не сделал в духе любезности: технически все еще разрешено правилами этой задачи использовать другую кодировку ввода и вывода для строки. Представляя любое
string
из его частично примененного церковного кодирования\f -> foldr f [] string :: (a -> [b] -> [b]) -> [b]
(с другой стороной биекции, обеспечиваемой функцией($ (:))
), получается($ \x->(x:).filter(x/=))
всего 24 символа.Я избегал публиковать 24-символьный ответ в качестве моего официального ответа, потому что вышеупомянутое решение могло быть опробовано на вышеуказанном интерпретаторе, поскольку
foldr(\x->(x:).filter(x/=))[]"Type unique chars!"
вместо этого было бы написано решение для игры в гольф:как сокращение для буквального объявления, которое было бы более безумным:
Но это совершенно верная версия структуры данных, представленная в виде чистых функций. (Конечно, вы
\f -> foldr f [] "Type unique chars!"
тоже можете использовать , но это, по-видимому, нелегитимно, так как он использует списки для фактического хранения данных, поэтому его часть свёртки должна, вероятно, быть скомпонована в функцию «ответ», что приведет к более чем 24 символам.)источник