Reduzieren Sie die Zeichenfolge auf einen Ausschnitt aus dem Alphabet

25

[a-zA-Z ]Reduzieren Sie eine nicht leere Zeichenfolge, die nur aus Groß- und Kleinbuchstaben und Leerzeichen ( ) besteht, auf einen Ausschnitt des Alphabets, beginnend mit dem ersten Zeichen.

Um eine Zeichenfolge zu verkleinern, beginnen Sie mit dem ersten alphabetischen Zeichen und entfernen Sie anschließend alle Zeichen, die nicht der nächste Buchstabe des Alphabets sind. Fahren Sie damit fort, bis Sie das Ende der Zeichenfolge erreichen.

Zum Beispiel codegolf:

Beginnen Sie mit c, entfernen oSie , da dies nicht der nächste Buchstabe des Alphabets ist.
Halten Sie, dwie es ist der nächste Buchstabe des Alphabets, und hält , ewie es auch der nächste Buchstabe ist.
Entfernen g, ound l, und zu halten f.

Ihr letzter Ausschnitt wäre dann cdef

Regeln

  • Die Kapitalisierung sollte aufrechterhalten werden, dies CodEgolFwürde zur Folge habenCdEF
  • Das Leerzeichen ist kein Buchstabe des Alphabets und sollte daher immer entfernt werden, auch wenn es der Anfang der Zeichenfolge ist
  • Aufgrund der Art der Reduzierung ist das erste alphabetische Zeichen der Eingabe immer das erste Zeichen der Ausgabe.
  • zZist der letzte Buchstabe des Alphabets. Es folgen keine Buchstaben, das Alphabet wird nicht wiederholt.

Testfälle

codegolf -> cdef
CodEgolf -> CdEf
 codeolfg -> cdefg
ProgrammingPuzzles -> P
Stack Exchange -> St
The quick red fox jumped over the lazy brown dog -> Tuvw
Zebra -> Z
Abcdegfhijkl -> Abcdef

Wertung

Dies ist , so dass nur wenige Bytes in jeder Sprache gewinnen!

Skidsdev
quelle
Aus dem vorletzten Testfall sehe ich, dass wenn wir erreichen, zwir einfach aufhören, oder?
Mr. Xcoder
@ Mr.Xcoder Richtig, siehe den letzten Punkt unter "Regeln"
Skidsdev
2
Bitte fügen Sie einen Testfall mit einem Leerzeichen am Anfang hinzu. Wie:<space>codegolf
Mr. Xcoder
Kann ich ein Array der ausgegebenen Buchstaben zurückgeben?
TheLethalCoder
1
@ Mr.Xcoder ja, Sie können
Skidsdev

Antworten:

12

JavaScript (ES6), 66 79 68 67 Byte

f=([c,...s],p)=>c?(p?~parseInt(c+p,36)%37:c<'!')?f(s,p):c+f(s,c):''

Wie?

Aufeinanderfolgende Buchstaben testen

Da das Konvertieren von zwei Zeichen in ihre ASCII-Codes in JS eine ziemlich lange Operation wäre, verwenden wir stattdessen die folgende Formel:

~parseInt(b + a, 36) % 37

Vorausgesetzt, dass sowohl a als auch b in sind [a-zA-Z ], ist der obige Ausdruck 0genau dann gleich, wenn a und b aufeinanderfolgende Buchstaben sind (dh aufeinanderfolgende Ziffern in der Basis 36), unabhängig vom Fall der Zeichen.

Zum Beispiel:

~parseInt("Y" + "x", 36) = ~(36 * parseInt("Y", 36) + parseInt("x", 36))
                         = ~(36 * 34 + 33)
                         = -(36 * 34 + 33 + 1)
                         = -(37 * 34)

Formatiert und kommentiert

f = ([c,                              // c = current character
         ...s],                       // s = array of remaining characters
                p) =>                 // p = previous matching letter
  c ? (                               // if there's still at least 1 character to process:
      p ?                             //   if p was already defined:
        ~parseInt(c + p, 36) % 37     //     test if p and c are NON-consecutive letters
      :                               //   else:
        c < '!'                       //     test if c is a space character
    ) ?                               //   if the above test passes:
      f(s, p)                         //     ignore c and keep the current value of p
    :                                 //   else:
      c + f(s, c)                     //     append c to the final result and update p to c
  :                                   // else:
    ''                                //   stop recursion

Testfälle

Arnauld
quelle
7

Python 2 , 69 Bytes

lambda s:reduce(lambda x,y:x+y*((ord(y)-ord(x[~0]))%32==1),s.strip())

Probieren Sie es online!

Eine einfache Reduzierung der Zeichenfolge. Wir verketten einfach das nächste Zeichen genau dann, wenn (ord(y)-ord(x[~0]))%32==1. Sehr hässliche Prüfung - ich bin sicher, dass es verbessert werden kann, aber ich bin nicht sicher, wie!

Sisyphus
quelle
Clevere Lösung! Schade, es ist nur Python 2: P
Mr. Xcoder
Sie können es mit Python 3 kompatibel machen from functools import*.
Totalhuman
1
@ThomasWard Totalhuman hat gerade anderen gesagt, wie man Python 3 kompatibel macht. Übrigens, import functools as fund f.ist viel länger als from functools import*sicher, sogar einmal verwendet. Weitere Informationen finden Sie in diesem Thread .
Mr. Xcoder
7

Python 3 , 75 85 84 91 81 77 75 Bytes

Ich denke, das ist so kurz wie es in Python 3 nur geht . Es kann in Python 2 um einige Bytes gekürzt werden, wie in Sisyphus 'Beitrag gezeigt .

  • EDIT: +10 zum Beheben eines Fehlers
  • BEARBEITEN: -1 durch Beheben eines anderen Fehlers
  • EDIT: +7 zur Behebung eines weiteren Fehlers
  • EDIT: -10 Bytes mit Hilfe von @Ruud
  • BEARBEITEN: -4 Bytes, da das OP die Ausgabe der durch einen Zeilenumbruch getrennten Buchstaben erlaubte
  • EDIT: -2 Bytes dank @Ruud , zurück zur ursprünglichen Byteanzahl !
s=input().strip();k=0
for i in s:
 if(ord(i)-ord(s[0]))%32==k:k+=1;print(i)

Probieren Sie es online!

Mr. Xcoder
quelle
Ich habe Verbesserungsvorschläge und werde bald auf dem Handy Golf spielen.
Mr. Xcoder
2
81 Bytes . Groß- und Kleinbuchstaben stimmen gut überein, wenn sie von 32
Arfie
@Ruud Das sind genau die Dinge, über die ich in meinem Kommentar redigiert habe.
Mr. Xcoder
79 Bytes
Arfie
8
Ich warte darauf, dass der Downvoter ihre Gründe erklärt.
Mr. Xcoder
6

05AB1E , 13 Bytes

áćsv¤yìuÇÆiy«

Probieren Sie es online!

-1 danke an Adnan

Erik der Outgolfer
quelle
Können Sie ersetzen ðKdurch á?
Adnan
@ Adnan Ich denke schon ...
Erik der Outgolfer
4

Brachylog , 15 Bytes

;ṢxS⊇.ḷ~sẠ∧Sh~h

Probieren Sie es online!

Dies wären 10 Bytes: ⊇.ḷ~sẠ&h~hOhne die ziemlich uninteressante Einschränkung "Zeichenfolgen können mit Leerzeichen beginnen".

Erläuterung

;ṢxS               S is the Input with all spaces removed
   S⊇.             The Output is an ordered subset of the Input
     .ḷ            The Output lowercased…
        ~sẠ          …is a substring of "abcdefghijklmnopqrstuvwxyz"
           ∧
            Sh     The first char of S…
              ~h   …is the first char of the Output

Da dies ziemlich aussagekräftig ist, ist dies auch sehr langsam.

Tödlich
quelle
Nun, zumindest schlägt es Jelly! Und außerdem glaube ich nicht, dass man das wirklich übertreiben kann ...
Erik the Outgolfer,
3

MATL , 18 16 15 Bytes

Vielen Dank an Mr.Xcoder für den Hinweis auf einen Fehler, der jetzt korrigiert wurde

Xz1&)"t@hkd1=?@

Buchstaben in der Ausgabe werden durch Zeilenumbrüche getrennt.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle (der Fußzeilencode zeigt der Übersichtlichkeit halber alle ausgegebenen Buchstaben in derselben Zeile an).

Erläuterung

Xz       % Implicitly input a string. Remove spaces
1&)      % Push first character and then the remaining substring
"        % For each
  t      %   Duplicate previous character
  @      %   Push current character
  h      %   Concatenate both characters
  k      %   Convert to lowercase
  d      %   Consecutive difference. Gives a number
  1=     %   Is it 1?
  ?      %   If so
    @    %     Push current char
         %   End (implicit)
         % End (implicit)
         % Display stack (implicit)
Luis Mendo
quelle
Sie haben vergessen, die Leerzeichen am Anfang der Zeichenfolge zu entfernen: Leerzeichen sind keine Buchstaben des Alphabets und sollten daher immer entfernt werden, auch wenn es der Anfang der Zeichenfolge ist .
Mr. Xcoder
@ Mr.Xcoder Danke! Korrigiert
Luis Mendo
3

Java (OpenJDK 8) , 102 101 74 Bytes

s->{char c=0;for(char x:s)if(c<1&x>32|~-x%32==c%32)System.out.print(c=x);}

Probieren Sie es online!

-27 Bytes dank @Olivier Grégoire

Nevay
quelle
1
75 Bytes: s->{char c=0;for(char x:s)if(c<33&x>33|~-x%32==c%32)System.out.print(c=x);}(mit char[]als Eingabe).
Olivier Grégoire
2

C # (Mono) , 129 107 93 91 87 Bytes

s=>{var r=s.Trim()[0]+"";foreach(var c in s)if(r[r.Length-1]%32==~-c%32)r+=c;return r;}

2 Bytes gespart dank @Mr. Xcoder.
4 Bytes dank @jkelm gespeichert.

Probieren Sie es online!

TheLethalCoder
quelle
Scheitert an führenden Leerzeichen
Skidsdev
@ Mayube Woops hat das nicht gesehen, behoben.
TheLethalCoder
2
91 Bytes . In C-ähnlichen Sprachen und Python (c-1)%32ist~-c%32
Mr. Xcoder
1
87 Bytes Sie nicht die getrimmte Zeichenfolge zuzuweisen , weil der Kontrollen in der for - Schleife müssen
jkelm
2

PHP, 64 + 1 Bytes

while($c=$argn[$i++])$c<A||$n&&($c&_)!=$n||(print$c)&$n=++$c&__;

Laufen Sie als Pipe mit -nRoder probieren Sie es online aus .


Neben den üblichen Tricks: Wenn $cerreicht Z, ++$cergibt AA,
und &__diese Länge unberührt bleibt; so $nwird es nicht weiter passen $c.

Titus
quelle
2

Haskell, 106 105 97 Bytes

import Data.Char
import Data.List
z=ord.toUpper
a%b|z a+1==z b=b|0<3=a
nub.scanl1(%).filter(>' ')

Ich habe versucht, fromEnum+ char-Arithmetik zu verwenden, anstatt zu importierenData.Char , aber das endete länger ...

8 Bytes gespart dank H.PWiz!

Probieren Sie es online aus.

Cristian Lupascu
quelle
102 Bytes mitfilter
H.PWiz
Oder 100 Bytes mitData.List
H.PWiz
@ H.PWiz Großartig! Vielen Dank!
Cristian Lupascu
2

Pyth, 21 20 18 Bytes

ef&qhThQhxGrT0tyr6

Probieren Sie es hier aus.

Weitaus effizientere 20-Byte-Version:

.U+b?t-CrZ1Creb1kZr6

Probieren Sie es hier aus.

-1 Danke an Herrn Xcoder (indirekt).

Erik der Outgolfer
quelle
Äquivalent: .U+b?tlrreb1rZ1kZrz6(denke ich). Dieser Trick hat mir allerdings geholfen.
Mr. Xcoder
@ Mr.Xcoder Wenn das ein Äquivalent wäre, hätte ich mit ein Byte sparen können, .U+b?tlrreb1rZ1kZr6aber leider r <str> 6bedeutet das A.strip(), nicht führende oder nachfolgende Leerzeichen nicht zu entfernen.
Erik der Outgolfer
Oh ja, ich habe nicht gesehen, dass Ihre Lösung von der Entfernung aller Leerzeichen
abhängt
@ Mr.Xcoder Umm, du solltest alle Leerzeichen entfernen.
Erik der Outgolfer
Nein, sollte ich nicht, da Leerzeichen einen ASCII-Wert von haben 32, während alle Buchstaben haben > 64und somit die Funktionalität nicht beeinträchtigen. Ich denke, das gilt auch für Ihre Antwort.
Mr. Xcoder
1

Perl 6 , 51 Bytes

{S:i:g/\s|(\w){}<([<!before "{chr $0.ord+1}">.]+//}

Probier es aus

Erweitert:

{  # bare block lambda with implicit parameter $_

  S                          # substitute implicitly on $_, not in-place
  :ignorecase
  :global
  /

    |  \s                    # match any space

    |  (\w)                  # match a word character
       {}                    # make sure $/ is updated (which $0 uses)

       <(                    # ignore everything before this

       [

           <!before "{       # make sure this won't match after this point
             chr $0.ord + 1  # the next ASCII character
           }">

           .                 # any character

       ]+                    # match it at least once

  //                         # remove what matched
}

Beachten Sie, dass dies <!before …>eine Aussage mit der Breite Null ist

Brad Gilbert b2gills
quelle
1

Japt , 18 17 16 Bytes

1 Byte dank @Shaggy gespeichert

x
c
Çc %H¥V%H©V°

Online testen!

Hatte gedacht, das wäre ein bisschen kürzer, aber ... So ist das Leben ...

Erläuterung

x    First line: set U to the result.
x    Trim all spaces off of the input. Only necessary to remove leading spaces.

c    Second line: set V to the result.
c    Take the charcode of the first character in U.

 Ç   c %H¥ V%H© V°
UoZ{Zc %H==V%H&&V++}   Final line: output the result.
UoZ{               }   Filter to only the chars in Z where
    Zc                   the charcode of Z
       %H                mod 32
         ==V%H           equals V mod 32.
              &&V++      If true, increment V for the next letter.
ETHproductions
quelle
Zumindest kürzer als meine 28-Byte-Travestie! : D Es sieht aus wie Sie ersetzen können rSmit x.
Shaggy,
1

C # (.NET Core) , 70 60 + 18 Bytes

-10 Bytes dank TheLethalCoder

a=>{var c=a.Trim()[0];return a.Where(x=>x%32==c%32&&++c>0);}

Die Byteanzahl umfasst auch:

using System.Linq;

Probieren Sie es online!

1 Byte länger (zur Zeit) (nicht mehr) als TheLethalCoder. Anderer Ansatz mit LINQ.

Dies nutzt zwei C-ähnliche Funktionen in C # - eine Zeichenvariable charverhält sich implizit wie eine Ganzzahl int, und der boolesche AND-Operator &&führt keine rechte Operation aus, wenn left a zurückgibt false. Code Erklärung:

a =>                                  // Take string as input
{
    var c = a.Trim()[0];              // Delete leading spaces and take first letter
    return a.Where(                   // Filter out characters from the string, leaving those that:
               x => x % 32 == c % 32  // it's the next character in alphabet case-insensitive (thanks to modulo 32 - credits to previous answers)
               && ++c > 0             // If it is, go to the subsequent character in alphabet (and this always has to return true)
           );
}
Grzegorz Puławski
quelle
Entfernen Sie das, .ToArray()indem Sie als ein zurückgeben IEnumerable<char>, um Bytes zu speichern.
TheLethalCoder
@TheLethalCoder richtig, ich habe gerade den Kommentar unter der Herausforderung gesehen. Vielen Dank!
Grzegorz Puławski
1

q / kdb + 47 45 Bytes

Lösung:

{10h$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}

Beispiele:

q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}"CodEgolf"
"CdEf"
q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}" codeolfg"
"cdefg"
q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}"ProgrammingPuzzles"
"P"
q){"c"$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x}"The quick red fox jumped over the lazy brown dog"
"Tuvw"

Erläuterung:

Nutzung des mod 32Tricks aus vorhandenen Lösungen zusammen mit der Konvergenzfunktion . Durchlaufen Sie die Zeichenfolge, wenn die Differenz zwischen dem letzten Element des Ergebnisses (z. B. beginnend mit T"The quick red fox ...") und dem aktuellen Zeichen 1 ist (nachdem mod32 eingegeben wurde), addieren wir dies zu das Ergebnis (also nehmen, warum wir nehmen last x), dann wirft alles zurück zu einer Zeichenfolge.

{10h$({(x;x,y)1=mod[y-last x;32]}/)7h$trim x} / the solution
{                                           } / lambda function
                                      trim x  / trim whitespace (leading/trailing)
                                   7h$        / cast string to ASCII (a -> 97)
     ({                         }/)           / converge
                    y-last x                  / y is the next item in the list, x contains results so far
              1=mod[        ;32]              / is the result mod 32 equal to 1
       (x;x,y)                                / if false, return x, if true return x concatenated with y
 10h$                                         / cast back to characters
Streetster
quelle
1

Perl 5 , 30 + 1 (-n) = 31 Bytes

/$b/i&&(print,$b=++$_)for/\S/g

Probieren Sie es online!

Wie?

/$b/i        # check if this letter equals the one in $b, ignore case
&&(print,    # output it if so
$b=++$_)     # store the next character to find
for/\S/g     # Looping over all non-whitespace characters
Xcali
quelle
0

Netzhaut , 76 Bytes

 

^.
$&$&$&¶
{T`@@L@l`@l@l@`..¶
T`l`L`.¶
(.)(.)((¶).*?(\1|\2)|¶.*)
$5$5$5$4

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

 

Leerzeichen löschen.

^.
$&$&$&¶

Verdreifachen Sie das erste Zeichen und fügen Sie ein Trennzeichen ein.

{T`@@L@l`@l@l@`..¶
T`l`L`.¶

Konvertieren Sie das zweite und dritte Zeichen in Kleinbuchstaben und erhöhen Sie sie. Konvertieren Sie letzteres in Großbuchstaben. Dies sind nun die Suchzeichen.

(.)(.)((¶).*?(\1|\2)|¶.*)
$5$5$5$4

Versuchen Sie, eines der Suchzeichen zu finden. Wenn es gefunden wird, verdreifachen Sie die Übereinstimmung, wodurch die Schleife für die nächste Suche neu gestartet wird. Andernfalls löschen Sie einfach die Suchzeichen und den Rest der Eingabe.

Neil
quelle
0

8 , 114 Bytes

Code

: z dup n:1+ 32 bor >r "" swap s:+ . ; 
: f s:trim 0 s:@ z ( nip dup 32 bor r@ n:= if rdrop z then ) s:each rdrop ;

Erläuterung

: z             \ n -- (r: x)
                \ print letter and save on r-stack OR-bitwised ASCII code of following letter
  dup           \ duplicate item on TOS
  n:1+          \ get ASCII code of the following letter
  32 bor        \ bitwise OR of ASCII code and 32 
  >r            \ save result on r-stack
  "" swap s:+ . \ print letter
;

: f        \ s -- 
  s:trim   \ remove trailing whitespace
  0 s:@    \ get 1st letter
  z        \ print 1st letter and save on r-stack OR-bitwised ASCII code of following letter
  ( nip    \ get rid of index
    dup    \ duplicate item on TOS
    32 bor \ bitwise OR of current ASCII code and 32 
    r@     \ get value stored on r-stack
    n:=    \ compare values to see if letter is printable or not
    if 
      rdrop \ clean r-stack
      z     \ print letter and save on r-stack OR-bitwised ASCII code of following letter
    then 
  ) 
  s:each    \ handle each character in string
  rdrop     \ clean r-stack
;

Beispiel

ok> " The quick red fox jumped over the lazy brown dog" f
Tuvw
Chaos Manor
quelle
0

Pyth, 15 Bytes

eo,}r0NG_xQhNty

Testsuite

Im Gegensatz zu allen anderen Antworten wird hierdurch die Ausgabe nicht zusammengehalten, sondern es werden alle Teilsequenzen der Eingabe generiert. Anschließend werden sie angewiesen, die gewünschte Zeichenfolge am Ende zu platzieren und auszugeben.

isaacg
quelle
Ich denke, Sie müssen überprüfen, ob der erste Buchstabe der Ausgabe auch der erste Buchstabe der Eingabe ist. Und ich denke, die Erstbestellung ist wichtig.
Erik der Outgolfer
@EriktheOutgolfer Entschuldigung, sagen Sie, die Antwort ist falsch? Ich stelle sicher, dass die Sequenz, deren erstes Zeichen in der Eingabe am frühesten ist, unter allen Teilsequenzen, die in alphabetischer Reihenfolge vorliegen, diejenige ist, die bis zum Ende sortiert ist. Sehen Sie sich den Testfall an, der mit einem Leerzeichen beginnt.
Isaacg
Können Sie bitte eine Erklärung hinzufügen? Ich habe vielleicht etwas falsch verstanden oder so ...
Erik the Outgolfer
0

J, Teillösung

Ich poste dies vor allem für Feedback und Verbesserungsvorschläge. Es funktioniert, kümmert sich aber nicht um Groß- und Kleinschreibung und ist schon lang für J.

Zuerst ein dyadisches Hilfsverb, das dir sagt, ob das linke und das rechte Argument alphabetisch benachbart sind:

g=.(= <:)&(a.&i.)  NB. could save one char with u:

Als nächstes ein Verb, das das erste Element entfernt, das nicht Teil eines alphabetischen Streifens ist, beginnend mit dem ersten Element:

f=.({~<^:3@>:@i.&0@(0,~2&(g/\))) ::]

Beachten Sie, dass wir Adverse verwenden :: , um das gesamte Argument unverändert zurückzugeben, wenn kein Nicht-Streifen-Element gefunden wurde (dh, wenn das gesamte Argument ein gültiger alphabetischer Streifen ist).

Schließlich wird die Lösung gegeben, indem fbis zur Konvergenz angewendet wird:

f^:_ 'codegolf'  NB. => 'cdef'

Probieren Sie es online!


Und hier ist eine geparste Version fzum leichteren Lesen:

           ┌─ ~ ─── {                         
           │                              ┌─ <
           │                       ┌─ ^: ─┴─ 3
           │                 ┌─ @ ─┴─ >:      
       ┌───┤           ┌─ @ ─┴─ i.            
       │   │     ┌─ & ─┴─ 0                   
       │   │     │                            
       │   └─ @ ─┤     ┌─ 0                   
── :: ─┤         │     ├─ ~ ─── ,             
       │         └─────┤                      
       │               │     ┌─ 2             
       │               └─ & ─┴─ \ ─── / ──── g
       └─ ]         

Nebenfrage : Warum werden die Box-Zeichen bei der Anzeige auf SO nicht perfekt ausgerichtet (sie funktionieren in meiner Konsole):

Jona
quelle