두 번째로 반복되지 않는 캐릭터는 무엇입니까?


18

Code Review 의이 질문을 바탕으로

비어 있지 않은 인쇄 가능한 ASCII 문자 문자열이 주어지면 두 번째 반복되지 않는 문자를 출력하십시오 . 예를 들어, input DEFD, output F입니다.

입력

산출

  • 두 번째 적절한 형식으로 다시 왼쪽으로가 오른쪽 읽을 때, 반복하지 않는 캐릭터.
  • 출력 문자는 대소 문자를 구분하지 않습니다.
  • 이러한 문자가 없으면 (예 : 모든 문자가 반복되는 경우) 빈 문자열을 출력하십시오.

규칙

  • 알고리즘은 대소 문자를 무시해야합니다. 이며, 그 Dd같은 문자로 수입니다.
  • 전체 프로그램 또는 기능이 허용됩니다.
  • 입력 문자열은 비어 있지 않아야합니다 (즉, 하나 이상의 문자 길이).
  • 입력 문자열은 ASCII입니다. 영숫자뿐만 아니라 모든 유효한 문자를 반복 할 수 있습니다 (공백 포함).
  • 표준 허점 은 금지되어 있습니다.
  • 이것은 이므로 모든 일반적인 골프 규칙이 적용되며 가장 짧은 코드 (바이트)가 이깁니다.

입력이 첫 번째 라인에 있고 출력이 두 번째 라인에 있습니다.

DEFD
F

FEED
D

This is an example input sentence.
x

...,,,..,,!@
@

ABCDefgHijklMNOPqrsTuVWxyz
B

AAAAAABBBBB


Thisxthis


This this.
.

8
대소 문자를 구분하지 않으면 Forth에서 수행하는 것이 좋습니다. 그러나 문자열 연산은 그 언어로 빨라집니다.
mbomb007

내 언어가 소문자를 지원하지 않으면 어떻게됩니까?
Adám

@ Adám 다른 코드 페이지를 사용합니까? 소문자를 지원하지 않는 경우 일반적으로 ASCII 문자열을 어떻게 입력합니까?
AdmBorkBork

1
내가 생각한 시스템에는 7 비트 코드 페이지가있었습니다. 대문자가 소문자 위치를 차지하고 대문자 위치가 글리프에 사용되는 수정 된 표준 코드 페이지 이것은 이전 APL 시스템에서 수행되었으므로 Shift 키를 사용하여 APL 글리프에 액세스 할 수 있었으며, 시프트되지 않은 문자는 고전적인 코딩 스타일의 대문자였습니다.
Adám

답변:


10

MATL , 11 바이트

tk&=s1=)FT)

반복되지 않는 두 번째 문자가 없으면 오류 (기본적으로 허용됨)와 함께 종료됩니다.

온라인으로 사용해보십시오!

설명

t      % Implicitly take input string. Duplicate
k      % Convert to lowercase
&=     % 2D array of equality comparisons
s      % Sum of each column
1=     % True for entries that equal 1
)      % Apply logical index to the input string to keep non-repeated characters
TF)    % Apply logical index to take 2nd element if it exists. Implicitly display 

닌자 편집이 다시 시작됩니다. : P
Dennis

@Dennis Hahaha. 글쎄, 난 당신이 곧 몇 바이트를 제거 할 것 같아요
Luis Mendo

10

망막 , 25 바이트

i!2=`(.)(?<!\1.+)(?!.*\1)

온라인으로 사용해보십시오! 첫 번째 줄은 여러 입력의 테스트 스위트에서 코드를 실행할 수있게합니다.

설명

이것은 정규 표현식과 일치하는 단일 정규 표현식입니다.

(.)(?<!\1.+)(?!.*\1)

즉, 문자를 일치시키고 입력의 다른 곳에 표시되지 않도록하십시오. 나머지는 구성입니다.

  • i 대소 문자를 구분하지 않습니다.
  • ! Retina에게 일치하는 수를 세는 것이 아니라 인쇄하도록 지시합니다.
  • 2= Retina에게 두 번째 일치 항목 만 인쇄하도록 지시합니다.

1
에 대해 가르쳐 주셔서 감사합니다 2=.
Leaky Nun

6

05AB1E, 15 12 바이트

l©v®y¢iy}}1@

설명

l©            # store lower case string in register
  v     }     # for each char in lower case string
   ®y¢iy      # if it occurs once in string, push it to stack
         }    # end if
          1@  # push the 2nd element from stack and implicitly display

온라인으로 사용해보십시오

@Adnan 덕분에 3 바이트 절약


또는 12 바이트 l©v®y¢iy}}1@:).
Adnan

@Adnan : 니스! @를 사용하지 않았다.
Emigna

5

파이썬 2, 59 58 바이트

단일 문자 목록 또는 출력이없는 경우 빈 목록을 반환합니다. (견고한 대소 문자 구분 ...)

s=input().lower();print[c for c in s if s.count(c)<2][1:2]

온라인으로 사용해보십시오



유효한 입력이 아닙니다. 사용자는 자신의 입력을 벗어날 필요가 없습니다.
mbomb007

4
당연히 그렇지. STDIN에 언어 목록 형식으로 목록을 제공합니다. 문자열이 다른 이유는 무엇입니까?
Dennis

5

젤리 , 11 바이트

Œlµḟœ-Q$Ḋḣ1

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

작동 원리

Œlµḟœ-Q$Ḋḣ1  Main link. Argument: s (string)

Œl           Convert s to lowercase.
  µ          Begin a new, monadic chain. Argument: s (lowercase string)
       $     Combine the two links to the left into a monadic chain.
      Q        Unique; yield the first occurrence of each character.
    œ-         Perform multiset subtraction, removing the last occurrence of each
               character.
   ḟ         Filterfalse; keep characters that do not appear in the difference.
        Ḋ    Dequeue; remove the first character.
         ḣ1  Head 1; remove everything but the first character.

4

배치, 171 바이트

@echo off
set a=.
set s=%~1
:l
if "%s%"=="" exit/b
set c=%s:~0,1%
call set t=%%s:%c%=%%
if "%s:~1%"=="%t%" set a=%a%%c%
set s=%t%
if "%a:~2%"=="" goto l
echo %c%

대체 형식, 171 바이트 :

@echo off
set a=.
set s=%~1
:l
if "%s%"=="" exit/b
set c=%s:~0,1%
set t=%s:~1%
call set s=%%s:%c%=%%
if "%s%"=="%t%" set a=%a%%c%
if "%a:~2%"=="" goto l
echo %c%

W2008R2에서 실행할 수 없습니다. "call set ..."행이 "call set t = % s : D = %"로 확장되고 "명령 구문이 잘못되었습니다"메시지와 함께 중단됩니다.
meden

@meden 죄송합니다. 일부 오타가 내 게시물에 들어갔습니다. 죽은 선물은 내가 말한 것보다 게시물이 짧았다는 것입니다! 그들은 지금 고정되어 있습니다.
Neil

3

Pyth, 16 15 바이트

@ mbomb007 덕분에 1 바이트

= rz1.xhtfq1 / zTzk
= rz1 : fq1 / zTz1 2

테스트 스위트.


2
나는 Pyth조차 모르지만, 그렇게 말한다면. : D
mbomb007

@ mbomb007 알다시피, [1:2]속임수.
Leaky Nun

t<…2대신에 바이트를 저장할 수 있습니다 :…1 2. 당신은 이동하여 다른 바이트를 저장할 수 있습니다 =rz1당신은 또한 변경하는 경우, 최초 사용 1Z(소문자 대신 대문자 출력) t<fq1/zT=rzZ2.
Anders Kaseorg

3

실제로는 19 바이트

;╗`ù╜ùc1=`░ε;(qq1@E

온라인으로 사용해보십시오!

설명:

;╗`ù╜ùc1=`░ε;(qq1@E
;╗                   push a copy of input to reg0
  `ù╜ùc1=`░          [v for v in s if
   ù╜ùc1=              s.lower().count(v.lower()) == 1]
           ε;(qq     append two empty strings to the list
                1@E  element at index 1 (second element)

3

C #, 129128 바이트

char c(string i){var s=i.Where((n,m)=>i.ToLower().Where(o=>o==Char.ToLower(n)).Count()<2).ToArray();return s.Length>1?s[1]:' ';}

잘 작동합니다. 나는 모든 것을 소문자로 할 필요가 없었 으면 좋겠다.


"Thisxthis"를 인수로 전달하면 IndexOutOfRangeException이 발생합니다. 그 외에는 == 1을 <2로 변경할 수 있다고 생각합니다.
Yytsi

2

Linq가 포함 된 C # 람다, 63 바이트

s=>(s=s.ToUpper()).Where(c=>s.Count(C=>c==C)<2).Skip(1).First()

당신은 대체 할 수 있어야 .Skip(1).First().ElementAt(1)
aloisdg 분석 재개 모니카 말한다

더 나은 당신은 목록으로 변환하고 색인을 사용할 수 있습니다.ToList()[1]
aloisdg는 Reinstate Monica

"", "AABB"및 "AABBC"와 같은 입력의 경우 두 번째 위치에 일치하는 문자가없는 경우 예외가 발생합니다. FirstOrDefault가 필요하다고 생각합니다.
Grax32

2

C #, 141 바이트

void p(){var x=Console.ReadLine().ToLower();var c=0;foreach(char i in x){if(x.Split(i).Length-1<2){if(++c==2){Console.WriteLine(i);break;}}}}

중단없이 (최소) 135 바이트

void p(){var x=Console.ReadLine().ToLower();var c=0;foreach(char i in x){if(x.Split(i).Length-1<2){if(++c==2){Console.WriteLine(i);}}}}

for (;;) 사용시 150 바이트

void p(){for(;;){var x=Console.ReadLine().ToLower();var c=0;foreach(char i in x){if(x.Split(i).Length-1<2){if(++c==2){Console.WriteLine(i);break;}}}}}

댓글이없는 언 골프

void p()
{
    var x=Console.ReadLine().ToLower();//Get lowercase version of input from STDIN
    var c=0; //Create "count" integer
    foreach(char i in x){//For each char in input from STDIN
        if(x.Split(i).Length-1<2)//If current char occurs once in input from STDIN
        {
            if(++c==2){ //Add 1 to count and if count is 2
                Console.WriteLine(i); //Print result to STDOUT
                break; //Exit foreach
            } //End of IF
         } //End of IF
     } //End of FOREACH
} //End of VOID

TuukkaX에 의해 12 바이트가 절약되었습니다 (횟수를 c로 변경).

TuukkaX (문자열을 var로 변경)에 의해 3 바이트가 저장됩니다.

"With for (;;)"에서 TuukkaX에 의해 4 바이트가 저장되었습니다 (while (true)에서 for (;;)로 변경됨).

TuukkaX에 의해 2 바이트가 절약되었습니다 (c ++; if (c == 2)를 if (++ c == 2)로 변경).

Bryce Wagner (x.ToCharArray ()를 x로 변경)가 14 바이트를 절약했습니다.


@TuukkaX 아, 정말로. 감사합니다!
r3pear

PPCG에 오신 것을 환영합니다! 좋은 첫 번째 게시물입니다! 규칙에 따르면이 문제에 대한 답변은 기능이나 전체 프로그램이어야하므로 코드를 약간 조정할 필요가 있습니다. 또한 사용하여 바이트를 저장할 수 있습니다 var대신 string과 같은 것을 가진 c대신을 count.
Yytsi

@TuukkaX 다시 감사합니다! 곧 코드를 수정하고 문자열을 var로 변경하겠습니다.
r3pear

@TuukkaX void program () {}과 같은 것을 추가해야합니까 ???
r3pear

예, 그러나 바이트를 저장하려면 1 바이트 함수 이름을 지정하십시오! :)
Yytsi

2

x86 기계 코드, 43 바이트

16 진수로 :

FC31C031C95641AC84C0740E3C6172F63C7A77F28066FFDFEBEC5EAC49740B89F751F2AE5974F44A77F1C3

함수는 (E) SI의 입력 문자열과 (E) DX의 정수에 대한 포인터를 가져 와서 (E) DX 번째 비 반복 문자를 반환하거나 해당 문자가 없으면 0을 반환합니다. 부작용으로 문자열을 대문자로 변환합니다.

분해 :

fc             cld
31 c0          xor    eax,eax
31 c9          xor    ecx,ecx
56             push   esi
_loop0:                         ;Search for the NULL char,
41             inc    ecx       ;counting the length in the process
ac             lodsb
84 c0          test   al,al
74 0e          je     _break0   ;NULL found, break
3c 61          cmp    al,0x61   ;If char is
72 f6          jb     _loop0    ;between 'a' and 'z'
3c 7a          cmp    al,0x7a   ;convert this char
77 f2          ja     _loop0    ;to uppercase in-place
80 66 ff df    and    byte ptr [esi-0x1],0xdf
eb ec          jmp    _loop0
_break0:
5e             pop    esi       ;Reset pointer to the string
_loop:                          ;ECX=string length with NULL
ac             lodsb            ;Load next char to AL
49             dec    ecx
74 0b          je     _ret      ;End of string found, break (AL==0)
89 f7          mov    edi,esi   ;EDI points to the next char
51             push   ecx
f2 ae          repnz scasb      ;Search for AL in the rest of the string
59             pop    ecx
74 f4          je     _loop     ;ZF==1 <=> another instance found, continue
4a             dec    edx
77 f1          ja     _loop     ;If not yet the EDX-th non-rep char, continue
_ret:
c3             ret

2

APL, 32 바이트

{⊃1↓⍵/⍨1=+/∘.=⍨(⎕UCS ⍵)+32×⍵∊⎕A}

시도 || 모든 테스트 사례

설명:

                (⎕UCS ⍵)+32×⍵∊⎕A  Add 32 to uppercase letters
            ∘.=⍨                    Make an equality matrix
          +/                        Check how many matches
    ⍵/⍨1=                           Keep elements with 1 match
  1↓                                Drop the first one
⊃                                   Return the second one

16 바이트로 게시하려고했지만 대소 문자를 구분하지 않아야한다는 것을 깨달았습니다 ...


1
(⎕UCS ⍵)+32×⍵∊⎕A819⌶⍵
Adám

나는 전에 그 연산자를 본 적이 없다. 어떤 버전에서 작동합니까?
Woofmao

이를 i- 빔 이라고합니다 . Dyalog APL의 모든 버전에서 운영자입니다. 원래는 IBM 시스템에 대한 특수 호출을 위해 이전 버전의 IBM APL 기능이었습니다. 알 겠어요? IBM — i- 빔 ?
Adám


글쎄, 나는 새로운 것을 배웠다. tryapl.org가 그것을 인식하지 못하는 것 같습니다. TIO 링크 만 사용해도 될까요?
Woofmao


1

Mathematica, 49 바이트

Cases[Tally@ToUpperCase@#,{_,1}][[2,1]]~Check~""&

익명의 기능. 문자 목록을 입력으로 사용합니다. 생성 된 오류를 무시하십시오.


1

자바 스크립트 (Firefox 48 이하), 60 바이트

f=s=>(m=s.match(/(.).*\1/i))?f(s.replace(m[1],"","gi")):s[1]

undefined반복되지 않는 문자가 없거나 하나만있는 경우를 반환 합니다. 문자열에 두 번 이상 나타나는 모든 문자를 대소 문자를 구분하여 삭제하여 작동합니다. Firefox 49에서 제거 된 비표준 Firefox 확장에 의존합니다. 119 91 바이트 ES6 버전 :

f=s=>(m=s.match(/(.).*?(\1)(.*\1)?/i))?f((m[3]?s:s.replace(m[2],"")).replace(m[1],"")):s[1]

문자열에서 두 번 이상 나타나는 모든 문자를 재귀 적으로 검색합니다. 문자가 정확히 두 번 나타나면 두 항목이 모두 삭제되고 그렇지 않으면 첫 번째 항목 만 삭제됩니다 (다른 항목은 나중에 삭제됨). 이를 통해 발생에 차이가있을 수 있습니다.


m[1]new RegExp(`${m[1]}`,"gi")
Value Ink

@ KevinLau-notKenny 특수 문자에서는 작동하지 않으며 특수한 경우 33 바이트가 소요되어 불행히도 93까지 증가했습니다.
Neil

noooooo는 특별한 캐릭터가 아닙니다! 지금도 루비 답변을 수정해야했습니다.
가치 잉크

1

J, 25 바이트

(1{2{.]-.]#~1-~:)@tolower

용법

   f =: (1{2{.]-.]#~1-~:)@tolower
   f 'DEFD'
f
   f 'FEED'
d
   f 'This is an example input sentence.'
x
   f '...,,,..,,!@'
@
   f 'ABCDefgHijklMNOPqrsTuVWxyz'
b
   f 'AAAAAABBBBB'

   f 'Thisxthis'

   f 'This this.'
.

설명

(1{2{.]-.]#~1-~:)@tolower  Input: s
                  tolower  Converts the string s to lowercase
              ~:           Mark the indices where the first time a char appears
            1-             Complement it
         ]                 Identity function to get s
          #~               Copy only the chars appearing more than once
      ]                    Identity function to get s
       -.                  Remove all the chars from s appearing more than once
   2{.                     Take the first 2 chars from the result (pad with empty string)
 1{                        Take the second char at index 1 and return it

1

배쉬, 58 바이트

tr A-Z a-z>t
tr -dc "`fold -1<t|sort|uniq -u`"<t|cut -c2

주의 : 이렇게하면 t 라는 임시 파일이 생성 됩니다. 이미 존재하는 경우 덮어 씁니다.


1

C, 174 바이트

int c(char*s){int y=128,z=256,c[384],t;memset(c,0,z*6);for(;t=toupper(*s);s++){c[t]++?c[t]-2?0:c[z+(c[y+c[z+t]]=c[y+t])]=c[z+t]:c[z]=c[y+(c[z+t]=c[z])]=t;}return c[y+c[y]];}

이것은 가장 짧지는 않지만 매우 효율적인 구현입니다. 본질적으로 이중 링크 목록을 사용하여 순서가 지정된 후보 문자 세트를 유지하고 입력 문자열을 한 번만 스캔합니다. 문자 코드를 반환하거나 찾지 못하면 0을 반환합니다.

약간 ungolfed 버전 :

int c(char*s)
{
    int y=128,z=256,c[384],t;
    //It's basically c[3][128], but with linear array the code is shorter

    memset(c,0,z*6);

    for(;t=toupper(*s);s++)
    {
        c[t]++ ?        // c[0][x] - number of char x's occurrence
            c[t] - 2 ?  // > 0
                0       // > 1 - nothing to do  
                : c[z + (c[y + c[z + t]] = c[y + t])] = c[z + t]  // == 1 - remove char from the list
            : c[z] = c[y + (c[z + t] = c[z])] = t; // == 0 - add char to the end of the list
    }
    return c[y + c[y]];
}

1

C #, 143 바이트

char c(string s){var l=s.Select(o=>Char.ToLower(o)).GroupBy(x=>x).Where(n=>n.Count()<2).Select(m=>m.Key).ToList();return l.Count()>1?l[1]:' ';}

1

TSQL, 128 바이트

골프 :

DECLARE @ varchar(99)=',,zzzbb@kkkkkkJgg'

,@i INT=99WHILE @i>1SELECT
@i-=1,@=IIF(LEN(@)>LEN(x)+1,x,@)FROM(SELECT
REPLACE(@,SUBSTRING(@,@i,1),'')x)x PRINT SUBSTRING(@,2,1)

언 골프 드 :

DECLARE @ varchar(99)=',,zzzbb@kkkkkkJgg'

,@i INT=99

WHILE @i>1
  SELECT
    @i-=1,@=IIF(LEN(@)>LEN(x)+1,x,@)
  FROM
    (SELECT 
       REPLACE(@,SUBSTRING(@,@i,1),'')x
    )x

PRINT SUBSTRING(@,2,1)

깡깡이


1

루비, 53 바이트

입력은 STDIN이고 출력은 STDOUT입니다. Ruby에서 배열 또는 문자열 반환에서 인덱스 외부 위치nil 되어 인쇄되지 않습니다.

String#count전달 된 문자열의 발생 횟수를 계산하는 대신 해당 문자열의 각 문자에 대한 발생 횟수를 계산하기 때문에 Ruby에서 이상한 함수입니다. 일반적으로 성가 시지만 이번에는 이점을 활용할 수 있습니다. String#swapcase대문자와 소문자를 바꿉니다.

$><<gets.chars.reject{|c|$_.count(c+c.swapcase)>1}[1]

.-46 바이트 와 같은 특수 문자에 대해 안전하지 않은 이전 버전

$><<gets.chars.reject{|c|$_=~/#{c}.*#{c}/i}[1]

1

자바 8 172 157 바이트

(String s)->{s=s.toLowerCase();for(char i=0,c;s.length()>0;s=s.replace(c+"","")){c=s.charAt(0);if(!s.matches(".*"+c+".*"+c+".*")&&++i>1)return c;}return' ';}

-15 바이트. Dang 나는 그때 골프에 나쁜했다. ;)

설명:

여기에서 시도하십시오.

(String s)->{                          // Method with String parameter and character return-type
  s=s.toLowerCase();                   // Make the input-String lowercase
  for(char i=0,c;s.length()>0;         // Loop over the characters of `s`
      s=s.replace(c+"","")){           // And after every iteration, remove all occurrences of the previous iteration
    c=s.charAt(0);                     // Get the current first character
    if(!s.matches(".*"+c+".*"+c+".*")  // If it doesn't occur more than once
     &&++i>1)                          // And this was the second one we've found
      return c;                        // Return this second characters
  }                                    // End of loop
  return' ';                           // Else: return an empty character/nothing
}                                      // End of method

1

R , 79 바이트

function(z){y=tolower(el(strsplit(z,"")));x=table(y);y[y%in%names(x[x==1])][2]}

온라인으로 사용해보십시오!

나는 여기서 뭔가 골프를 치는 것처럼 느낍니다. 그러나 나는이 도전을 정말로 즐겼다.

이 답변은 문자열을 문자로 구성된 벡터로 나누고 모두 소문자로 변경하고 표로 계산합니다. 한 번 발생하는 문자를 선택하여 앞에서 언급 한 벡터 내의 문자와 비교하면 true 인 두 번째 값이 출력으로 반환됩니다. 빈 문자열 또는 반복 문자가없는 문자열은 NA를 출력합니다.





0

펄, 75 바이트

 my$s=<>;chomp$s;my$c;for my$i(split//,$s){my$m=@{[$s=~/$i/gi]};$m<2and++$c>=2and say$i and last}

0

자바 스크립트 (외부 라이브러리 사용) (107 바이트)

내가 쓴 라이브러리를 사용하여 이것을 분쇄했습니다. 해당 문자열 인 변수 "s"의 선언을 계산해야하는지 잘 모르겠습니다.

(s)=>_.From(s).ToLookup(y=>y.toLowerCase(),z=>z).Where(g=>g.Value.Count()==1).Select(x=>x.Key).ElementAt(1)

빈 문자열 입력, 반복되지 않는 문자가 하나만있는 입력 및 2 개 이상의 반복되지 않는 문자가있는 입력을 처리합니다.

Image 1


해당 도서관으로 연결되는 링크가 있습니까? 또한 이것은 코드 골프이기 때문에 가능한 공백을 제거해야합니다.
Value Ink

예, github.com/mvegh1/Enumerable 입니다. 아직 문서가 없습니다. 죄송합니다, 나는 많은 공백으로 줄이기 위해이 답변 정리합니다
applejacks01

아마도 답변 본문에서 언급하고 연결해야합니다. 또한 바이트 수와 관련하여 합의는 익명의 람다 (so s=> ...) 에 넣는 것입니다.
Value Ink

문제 없습니다. 내 코드에 연결하여 다른 사람을 화나게하고 싶지는 않지만 라이브러리를 사용했다고 언급했습니다. 알려 주셔서 감사합니다. 람다로 답변을 업데이트하겠습니다.
applejacks011

0

클로저, 109 바이트

#(let[s(clojure.string/lower-case %)](or(second(remove(set(map(fn[[k v]](if(> v 1)k))(frequencies s)))s))""))

더 간결한 방법이 있기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.