Гольф кода: дублирующееся символьное удаление в строке

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

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

30
задан 4 revs, 3 users 65% 23 May 2017 в 11:56
поделиться

45 ответов

Perl

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

perl -pe's/$1//gwhile/(.).*\1/'
26
ответ дан 27 November 2019 в 22:53
поделиться

VB.NET / LINQ

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

Dim p = New String ((From c In "nbHHkRvrXbvkn" Group c By c Into i = Count Где i = 1 Выберите c) .ToArray)

Полный рабочий оператор, с исходной строкой и отключенным специальным VB «Красивым листингом (переформатирование кода», 96 символов, нерабочий оператор без исходной строки в 84 символа.

(Убедитесь, что ваш код работает, прежде чем отвечать. Спасибо.)

3
ответ дан 27 November 2019 в 22:53
поделиться

Рубин - 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

19
ответ дан 27 November 2019 в 22:53
поделиться

APL

23 символа:

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

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

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

18
ответ дан 27 November 2019 в 22:53
поделиться

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)'
15
ответ дан 27 November 2019 в 22:53
поделиться

Haskell

Конечно, в Haskell есть более короткие способы сделать это, но:

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

Игнорирование let, поскольку оно требуется только для объявлений функций в GHCi, мы имеем hy = [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.

12
ответ дан 27 November 2019 в 22:53
поделиться

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

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

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
ответ дан 27 November 2019 в 22:53
поделиться

C #

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());
8
ответ дан 27 November 2019 в 22:53
поделиться

C #

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

71 символ

7
ответ дан 27 November 2019 в 22:53
поделиться

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 байт.

6
ответ дан 27 November 2019 в 22:53
поделиться

VB.NET

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

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

5
ответ дан 27 November 2019 в 22:53
поделиться

PowerShell

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

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

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

param($s)
$h=@{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}
$a
5
ответ дан 27 November 2019 в 22:53
поделиться

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('');
3
ответ дан 27 November 2019 в 22:53
поделиться

TCL

123 chars. It might be possible to get it shorter, but this is good enough for me.

proc h {i {r {}}} {foreach c [split $i {}] {if {[llength [split $i $c]]==2} {set r $r$c}}
return $r}
puts [h [gets stdin]]
3
ответ дан 27 November 2019 в 22:53
поделиться

C

Полная программа на 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);}
3
ответ дан 27 November 2019 в 22:53
поделиться

Scala

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

def s(s:String)=(""/:s)((a,b)=>if(s.filter(c=>c==b).size>1)a else a+b)
3
ответ дан 27 November 2019 в 22:53
поделиться

Ruby

63 символа.

puts (t=gets.split(//)).map{|i|t.count(i)>1?nil:i}.compact.join
3
ответ дан 27 November 2019 в 22:53
поделиться

C

(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, Без включения EOF не определен, поэтому вместо этого я использовал -1 (и получил символ). Эта программа работает только по назначению для входов, содержащих менее 100000 символов!

Версия 2, с благодарностью strager 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
3
ответ дан 27 November 2019 в 22:53
поделиться

LabVIEW 7.1

ONE символ, и это синяя константа « 1 » на блок-схеме. Клянусь, ввод был скопирован и вставлен; -)

http://i25.tinypic.com/hvc4mp.png

http://i26.tinypic.com/5pnas.png

38
ответ дан 27 November 2019 в 22:53
поделиться

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;
2
ответ дан 27 November 2019 в 22:53
поделиться

Haskell

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

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

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

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

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

I ' Предположим, вы понимаете версию Марка, поэтому я просто расскажу об изменении. Выражение Марка:

(<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 для «это значение не будет использоваться, поэтому я не собираюсь усложнять свой код, давая ему имя».

4
ответ дан 27 November 2019 в 22:53
поделиться

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

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

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

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

(1+=/¨(x∘∊¨x))/x
6
ответ дан 27 November 2019 в 22:53
поделиться

JavaScript 1.6

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

Короче, чем ранее опубликованный раствор JavaScript 1.8 (71 символ VS 85)

3
ответ дан 27 November 2019 в 22:53
поделиться

C # (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());
2
ответ дан 27 November 2019 в 22:53
поделиться

И по пути, как вы сказали, что вопрос «не ограничивается C++»:

1) динамические языки, конечно, сделать его куском торта:

# python
def func(i):
  if i == 0:
    return 0
  elif i == 1:
    return "zero"
  else
    return ()

2) некоторые функциональные языки (Haskell, OCaml, Scala, F #) предоставляют хорошие встроенные варианты, которые называются алгебраические типы данных (статья имеет хорошие образцы).

-121--2874463-

Вы просмотрели/использовали набор тестов Джона Грубера ?

-121--1597785-

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

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

Пример:

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

Требуется только негласное выполнение скобок. Если ввести глагол, то сам код будет состоять из 14 символов.

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

EDIT: Более умный способ, о котором идет речь:

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

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

14
ответ дан 27 November 2019 в 22:53
поделиться

Haskell Pointfree

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

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

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

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

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

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

2
ответ дан 27 November 2019 в 22:53
поделиться

C: 83 89 93 99 101 символов

  • O (n 2 ) раз.
  • Ограничено 999 символами.
  • Работает только в 32-битном режиме (из-за отсутствия #include -ing (стоит 18 символов), поэтому возвращаемый тип получает интерпретируется как int и отбрасывает половину бит адреса).
  • Показывает дружеское «предупреждение: эта программа использует gets (), что небезопасно». на Mac.

.

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

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

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

)

5
ответ дан 27 November 2019 в 22:53
поделиться

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

fold -w1|sort|uniq -u|paste -s -d ''
2
ответ дан 27 November 2019 в 22:53
поделиться

Golfscript (sym) - 15

  .`{\{=}+,,(!}+,
+-------------------------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |    |    |    |    |  |
|0         10        20        30        40        50        60        70 |
|                                                                         |
+-------------------------------------------------------------------------+
5
ответ дан 27 November 2019 в 22:53
поделиться

Ассемблер

Протестировано с помощью WinXP DOS box (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
3
ответ дан 27 November 2019 в 22:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: