Подтвердить что ты не робот

Code Golf: повторное удаление символов в строке

Задача: самый короткий код, число символов, которое обнаруживает и удаляет повторяющиеся символы в String. Удаление включает в себя ВСЕ экземпляры дублированного символа (поэтому, если вы обнаружите 3 n, все три должны идти), а оригинальный порядок символов должен быть сохранен.

Пример ввода 1:
   nbHHkRvrXbvkn

Пример Результат 1:
   RRx


Пример ввода 2:
   nbHHkRbvnrXbvkn

Результат 2:
   RRx

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

(Это основано на моем другом вопросе, где мне нужен был самый быстрый способ сделать это на С#, но я думаю, что он делает хороший Code Golf на разных языках.)

4b9b3361

Ответ 2

Perl

21 символ perl, 31 для вызова, 36 суммарных нажатий клавиш (счетный сдвиг и окончательный возврат):

perl -pe's/$1//gwhile/(.).*\1/'

Ответ 3

Ruby - 61 53 51 56 35

61 символ, говорит правитель. (Дает мне идею для другого кодового гольфа...)

  puts ((i=gets.split(''))-i.select{|c|i.to_s.count(c)<2}).join
+-------------------------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |    |    |    |    |  |
|0         10        20        30        40        50        60        70 |
|                                                                         |
+-------------------------------------------------------------------------+
  gets.chars{|c|$><<c[$_.count(c)-1]}

... 35 автор Nakilon

Ответ 4

АПЗ

23 символа:

(((1+ρx)-(ϕx)ιx)=xιx)/x

Я новичок APL (узнал это вчера), поэтому будьте добрым - это, конечно, не самый эффективный способ сделать это. Мне стыдно, что я не сильно избил Перла.

И снова, может быть, он говорит что-то, когда самый естественный способ для новичков решить эту проблему в APL был еще более кратким, чем любое другое решение на любом языке.

Ответ 5

Python:

s=raw_input()
print filter(lambda c:s.count(c)<2,s)

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

python -c 's=raw_input();print filter(lambda c:s.count(c)<2,s)'

Ответ 6

J ( 16 12 символов)

(~.{~[:I.1=#/.~)

Пример:

(~.{~[:I.1=#/.~) 'nbHHkRvrXbvkn'
    RrX

Это нужно, чтобы скобки выполнялись молчаливо. Если положить в глагол, фактический код сам будет 14 символов.

Конечно, есть более разумные способы сделать это.

EDIT: более разумный способ:

(~.#~1=#/.~) 'nbHHkRvrXbvkn'
    RrX

12 символов, только 10, если задано в глаголе. Я все еще ненавижу тот факт, что он дважды перебирает список, один раз подсчитывает (#/.), А другой возвращает uniques (nub или ~.), Но даже нубкомпонент, стандартный глагол в библиотеке "misc" делает это дважды.

Ответ 7

Haskell

В Haskell, конечно, есть более короткие способы, но:

Prelude Data.List> let h y=[x|x<-y,(<2).length$filter(==x)y]
Prelude Data.List> h "nbHHkRvrXbvkn"
"RrX"

Игнорирование let, так как оно требуется только для объявлений функций в GHCi, мы имеем h y=[x|x<-y,(<2).length$filter(==x)y], что составляет 37 символов (это связывает текущий "ядро" Python "".join(c for c in s if s.count(c)<2), и в любом случае это практически тот же код).

Если вы хотите сделать из него всю программу,

h y=[x|x<-y,(<2).length$filter(==x)y]
main=interact h

$ echo "nbHHkRvrXbvkn" | runghc tmp.hs
RrX

$ wc -c tmp.hs
54 tmp.hs

Или мы можем сбить одного персонажа таким образом:

main=interact(\y->[x|x<-y,(<2).length$filter(==x)y])

$ echo "nbHHkRvrXbvkn" | runghc tmp2.hs
RrX

$ wc -c tmp2.hs
53 tmp2.hs

Он работает на всех stdin, а не по строкам, но это кажется приемлемым IMO.

Ответ 8

C89 (106 символов)

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

b[256];l;x;main(c){while((c=getchar())>=0)b[c]=b[c]?1:--l;
for(;x-->l;)for(c=256;c;)b[--c]-x?0:putchar(c);}

В одной строке это 58 + 48 = 106 байт.

C89 (173 символа)

Это был мой оригинальный ответ. Как сказано в комментариях, это не работает слишком хорошо...

#include<stdio.h>
main(l,s){char*b,*d;for(b=l=s=0;l==s;s+=fread(b+s,1,9,stdin))b=realloc(b,l+=9)
;d=b;for(l=0;l<s;++d)if(!memchr(b,*d,l)&!memchr(d+1,*d,s-l++-1))putchar(*d);}

В двух строках оно равно 17 + 1 + 78 + 77 = 173 байта.

Ответ 9

С#

65 Персонажи:

new String(h.Where(x=>h.IndexOf(x)==h.LastIndexOf(x)).ToArray());

67 Символы с переназначением:

h=new String(h.Where(x=>h.IndexOf(x)==h.LastIndexOf(x)).ToArray());

Ответ 10

С#

new string(input.GroupBy(c => c).Where(g => g.Count() == 1).ToArray());

71 символ

Ответ 11

PHP (136 символов)

<?PHP
function q($x){return $x<2;}echo implode(array_keys(array_filter(
array_count_values(str_split(stream_get_contents(STDIN))),'q')));

В одной строке это 5 + 1 + 65 + 65 = 136 байтов. Используя PHP 5.3, вы можете сохранить несколько байтов, делая функцию анонимной, но я не могу проверить это сейчас. Возможно, что-то вроде:

<?PHP
echo implode(array_keys(array_filter(array_count_values(str_split(
stream_get_contents(STDIN))),function($x){return $x<2;})));

Это 5 + 1 + 66 + 59 = 131 байт.

Ответ 12

другое решение APL

В качестве динамической функции (18 символов)

{(1+=/¨(ω∘∊¨ω))/ω}

предполагая, что вход находится в переменной x (16 символов):

(1+=/¨(x∘∊¨x))/x

Ответ 13

VB.NET

For Each c In s : s = IIf(s.LastIndexOf(c) <> s.IndexOf(c), s.Replace(CStr(c), Nothing), s) : Next

Конечно, VB не является оптимальным языком для сохранения символов, но строка выводится на 98 символов.

Ответ 14

PowerShell

61 символ. Где $s="nbHHkRvrXbvkn" и $a - результат.

[email protected]{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}

Полностью функционирующий параметризованный script:

param($s)
[email protected]{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}
$a

Ответ 15

C: 83 89 93 99 101 characters

  • O (n 2).
  • Ограничено до 999 символов.
  • Работает только в 32-битном режиме (из-за не #include -ing <stdio.h> (стоит 18 символов), в результате чего тип возврата gets интерпретируется как int и прерывает половину адресных битов).
  • Показывает дружественное предупреждение: в этой программе используется функция gets(), которая небезопасна. " на компьютерах Mac.

.

main(){char s[999],*c=gets(s);for(;*c;c++)strchr(s,*c)-strrchr(s,*c)||putchar(*c);}

(и эта аналогичная версия 82 -chars принимает входные данные через командную строку:

main(char*c,char**S){for(c=*++S;*c;c++)strchr(*S,*c)-strrchr(*S,*c)||putchar(*c);}

)

Ответ 16

Golfscript (sym) - 15

  .`{\{=}+,,(!}+,
+-------------------------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |    |    |    |    |  |
|0         10        20        30        40        50        60        70 |
|                                                                         |
+-------------------------------------------------------------------------+

Ответ 17

Хаскел

(просто сбив несколько персонажей с работы Марка Рушакова, я бы предпочел, чтобы он был опубликован как комментарий к нему)

h y=[x|x<-y,[_]<-[filter(==x)y]]

что лучше идиомы Haskell, но, возможно, сложнее следовать за не-Haskellers, чем это:

h y=[z|x<-y,[z]<-[filter(==x)y]]

Изменить, чтобы добавить объяснение для hiena и других:

Я предполагаю, что вы понимаете версию Mark, поэтому я просто расскажу об этом изменении. Выражение Mark:

(<2).length $ filter (==x) y

фильтрует y, чтобы получить список элементов, который == x, находит длину этого списка и делает его менее двух. (на самом деле он должен быть длиной один, но ==1 длиннее <2) Моя версия:

[z] <- [filter(==x)y]

делает тот же фильтр, затем помещает полученный список в список как единственный элемент. Теперь стрелка (предназначенная для того, чтобы выглядеть как установленное включение!) Говорит "для каждого элемента списка RHS по очереди, назовите этот элемент [z]". [z] - это список, содержащий единственный элемент z, поэтому элемент "filter(==x)y" может быть вызван только "[z]", если он содержит ровно один элемент. В противном случае он отбрасывается и никогда не используется как значение z. Таким образом, z (которые возвращаются слева от | в понимании списка) представляют собой именно тег x, который возвращает filter список длины один.

Это была моя вторая версия, моя первая версия возвращает x вместо z - потому что они одинаковы в любом случае - и переименовывает z в _, который является символом Haskell для "this value isn ' t будет использоваться, поэтому я не буду усложнять свой код, указав ему имя".

Ответ 18

Javascript 1.8

s.split('').filter(function (o,i,a) a.filter(function(p) o===p).length <2 ).join('');

или поочередно - аналогично примеру python:

[s[c] for (c in s) if (s.split("").filter(function(p) s[c]===p).length <2)].join('');

Ответ 19

TCL

123 символа. Возможно, это станет возможно короче, но для меня это достаточно хорошо.

proc h {i {r {}}} {foreach c [split $i {}] {if {[llength [split $i $c]]==2} {set r $r$c}}
return $r}
puts [h [gets stdin]]

Ответ 20

рубин

63 символа.

puts (t=gets.split(//)).map{|i|t.count(i)>1?nil:i}.compact.join

Ответ 21

VB.NET/LINQ

96 символов для полного рабочего заявления

Dim p=New String((From c In"nbHHkRvrXbvkn"Group c By c Into i=Count Where i=1 Select c).ToArray)

Полная рабочая инструкция с оригинальной строкой и спецификацией VB "Прекрасное перечисление (переформатирование кода) отключено на 96 символов, нерабочий оператор без оригинальной строки с 84 символами.

(Пожалуйста, убедитесь, что ваш код работает до ответа. Спасибо.)

Ответ 22

Scala

54 символа только для тела метода, 66 с объявлением метода (статически типизированное):

def s(s:String)=(""/:s)((a,b)=>if(s.filter(c=>c==b).size>1)a else a+b)

Ответ 23

С

Полная программа в C, 141 байт (подсчет новых строк).

#include<stdio.h>
c,n[256],o,i=1;main(){for(;c-EOF;c=getchar())c-EOF?n[c]=n[c]?-1:o++:0;for(;i<o;i++)for(c=0;c<256;c++)n[c]-i?0:putchar(c);}

Ответ 24

С

(1-я версия: 112 символов, 2-я версия: 107 символов)

k[256],o[100000],p,c;main(){while((c=getchar())!=-1)++k[o[p++]=c];for(c=0;c<p;c++)if(k[o[c]]==1)putchar(o[c]);}

Это

/* #include <stdio.h> */
/* int */ k[256], o[100000], p, c;
/* int */ main(/* void */) {
  while((c=getchar()) != -1/*EOF*/) {
    ++k[o[p++] = /*(unsigned char)*/c];
  }
  for(c=0; c<p; c++) {
    if(k[o[c]] == 1) {
      putchar(o[c]);
    }
  }
  /* return 0; */
}

Поскольку getchar() возвращает int и putchar принимает int, #include может "безопасно" удаляться. Без include, EOF не определен, поэтому вместо него я использовал -1 (и получил char). Эта программа работает только для входов с количеством символов менее 100000!

Версия 2 с благодарностью 107 символов

#ifdef NICE_LAYOUT
#include <stdio.h>

/* global variables are initialized to 0 */
int char_count[256];                          /* k in the other layout */
int char_order[999999];                       /* o ... */
int char_index;                               /* p  */

int main(int ch_n_loop, char **dummy)         /* c  */
                                              /* variable with 2 uses */
{

  (void)dummy; /* make warning about unused variable go away */

  while ((ch_n_loop = getchar()) >= 0) /* EOF is, by definition, negative */
  {
    ++char_count[ ( char_order[char_index++] = ch_n_loop ) ];
    /* assignment, and increment, inside the array index */
  }
  /* reuse ch_n_loop */
  for (ch_n_loop = 0; ch_n_loop < char_index; ch_n_loop++) {
    (char_count[char_order[ch_n_loop]] - 1) ? 0 : putchar(char_order[ch_n_loop]);
  }
  return 0;
}
#else
k[256],o[999999],p;main(c){while((c=getchar())>=0)++k[o[p++]=c];for(c=0;c<p;c++)k[o[c]]-1?0:putchar(o[c]);}
#endif

Ответ 25

Javascript 1.6

s.match(/(.)(?=.*\1)/g).map(function(m){s=s.replace(RegExp(m,'g'),'')})

Короче, чем ранее размещенное решение Javascript 1.8 (71 символ против 85)

Ответ 26

Ассемблер

Протестировано с помощью окна WinXP DOS (cmd.exe):

    xchg cx,bp
    std
    mov al,2
    rep stosb
    inc cl
l0: ; to save a byte, I've encoded the instruction to exit the program into the
    ; low byte of the offset in the following instruction:
    lea si,[di+01c3h] 
    push si
l1: mov dx,bp
    mov ah,6
    int 21h
    jz l2
    mov bl,al
    shr byte ptr [di+bx],cl
    jz l1
    inc si
    mov [si],bx
    jmp l1
l2: pop si
l3: inc si
    mov bl,[si]
    cmp bl,bh
    je l0+2
    cmp [di+bx],cl
    jne l3
    mov dl,bl
    mov ah,2
    int 21h
    jmp l3

Собирается до 53 байтов. Считывает стандартный ввод и записывает результаты в стандартный вывод, например:

 programname < input > output

Ответ 27

PHP

118 символов действительного кода (плюс 6 символов для тега блока PHP):

<?php
$s=trim(fgets(STDIN));$x='';while(strlen($s)){$t=str_replace($s[0],'',substr($s,1),$c);$x.=$c?'':$s[0];$s=$t;}echo$x;

Ответ 28

С# (53 символа)

Где s - ваша строка ввода:

new string(s.Where(c=>s.Count(h=>h==c)<2).ToArray());

Или 59 с повторным назначением:

var a=new string(s.Where(c=>s.Count(h=>h==c)<2).ToArray());

Ответ 29

Haskell Pointfree

import Data.List
import Control.Monad
import Control.Arrow
main=interact$liftM2(\\)nub$ap(\\)nub

Вся программа - 97 символов, но реальное мясо составляет всего 23 символа. Остальное - это просто импорт и приведение функции в монаду IO. В ghci с загруженными модулями просто

(liftM2(\\)nub$ap(\\)nub) "nbHHkRvrXbvkn"

В еще более смешном стиле без очков (бессмысленный стиль?):

main=interact$liftM2 ap liftM2 ap(\\)nub

Это немного дольше, хотя на 26 символов для самой функции.

Ответ 30

Shell/Coreutils, 37 символов

fold -w1|sort|uniq -u|paste -s -d ''