Füllen Sie die Lücken gegenseitig aus

11

Bei einer Eingabe von zwei Zeichenfolgen mit Sequenzen von Unterstrichen, die entsprechende Wörter darstellen, werden die Sätze mit den ausgefüllten "Leerzeichen" ausgegeben.

Diese Herausforderung lässt sich am besten anhand eines Beispiels beschreiben. Hier ist eine Beispieleingabe:

programming _____________ and code golf
programming puzzles ______ code ____

Und hier ist die entsprechende Ausgabe:

programming ___puzzles___ and code golf
programming puzzles _and__ code golf

Für die Zwecke dieser Herausforderung wird ein "Wort" als eine Folge von einem oder mehreren Kleinbuchstaben definiert, und ein "Leerzeichen" wird als ein oder mehrere Unterstriche definiert (die Eingabe enthält immer nur Kleinbuchstaben, Leerzeichen und Unterstriche). . Wörter und Leerzeichen in den Eingabezeichenfolgen werden durch einzelne Leerzeichen getrennt, und die Summe der Anzahl der Wörter und Leerzeichen in den Sätzen ist immer gleich.

Das Ziel der Herausforderung besteht darin, alle Lücken mit den richtigen Wörtern zu füllen. Dies sind die Wörter, die denselben Index in der anderen Zeichenfolge belegen, wenn sie durch Leerzeichen geteilt werden.

  • Das Wort muss im Leerzeichen zentriert sein, wie im obigen Beispiel mit dem Wort "Rätsel" gezeigt - auf beiden Seiten verbleibt die gleiche Anzahl von Unterstrichen.

  • Wenn das Wort nicht genau zentriert werden kann, kann der zusätzliche Unterstrich entweder links oder rechts stehen (z. B. das Wort "und" im obigen Beispiel).

  • Es wird immer genug Unterstriche geben, damit das Wort passt, aber es kann genau so viele wie die Länge des Wortes geben (z. B. das Wort "Golf" im obigen Beispiel).

  • In beiden Zeichenfolgen wird niemals ein Leerzeichen an derselben Position angezeigt.

Die Eingabe / Ausgabe kann eine der folgenden sein (Eingabe / Ausgabe muss nicht unbedingt über dieselbe Methode erfolgen):

  • einzelne Zeichenfolge, die durch ein nicht alphabetisches Zeichen, ein Leerzeichen oder einen Unterstrich getrennt ist (z. B. durch Zeilenumbrüche oder Kommas getrennte Zeichenfolge)

  • ein Array / eine Liste / etc. von zwei Saiten

  • zwei Funktions- / Befehlszeilenargumente (nur Eingabe)

Da dies , gewinnt der kürzeste Code in Bytes.

Das obige Beispiel kann als Testfall verwendet werden. Hier ist ein größerer Testfall (die zweite Zeichenfolge in der Ausgabe kann aufgrund des unterschiedlichen Zentrierungsverhaltens geringfügig variieren):

lorem _____ dolor _____ amet _______________ adipiscing elit mauris dapibus tincidunt _____________________________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum ______ sit _______ consectetur _______________ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem ____________________________ dictum

lorem ipsum dolor _sit_ amet __consectetur__ adipiscing elit mauris dapibus tincidunt ____________metus____________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum dolor_ sit _amet__ consectetur __adipiscing___ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem _________fermentum__________ dictum
Türknauf
quelle
Schöne bidirektionale Herausforderung.
Rɪᴋᴇʀ

Antworten:

5

Pyth, 30

jL;Cmm|*}J\_k.[lkhx#JdJkdCcR;Q

Nimmt Ein- und Ausgaben als Liste von zwei Zeichenfolgen. Verwendet einen ziemlich einfachen Split-Zip-Double-Map-Center-Zip-Join-Ansatz.

Probieren Sie es hier aus

Erweitert:

jL;Cmm|*}J\_k.[lkhx#JdJkdCcR;Q   ##
                          cR;Q   ##  split
                         C       ##  zip
    mm                           ##  double map
      |*}J\_k.[lkhx#JdJkd        ##  centre
   C                             ##  zip
jL;                              ##  join

Ich werde mehr erklären, sobald ich wirklich zufrieden bin, dass ich das nicht mehr spielen kann, obwohl es angesichts der Allgegenwart des Split-Zip-Double-Map-Center-Zip-Join-Ansatzes und allem ziemlich klar sein sollte.

FryAmTheEggman
quelle
8
Ahhh, der klassische Split-Zip-Double-Map-Center-Zip-Join-Ansatz. Ich erinnere mich gern daran, dass es in meiner Vorlesung zu Algorithmen 101 als einführendes Beispiel verwendet wurde.
Martin Ender
3
@ MartinBüttner Ja, ich habe einige schlechte Erinnerungen daran, weil ich diese Klasse durchgeschlafen habe und stattdessen Probleme bei der Prüfung mit dem Duplicate-Append-Lookback-Match-Add-Center-Ansatz lösen musste.
FryAmTheEggman
4
Ich werde etwas kaltes Wasser auf die Verbrennung auftragen.
Martin Ender
7

Retina , 102 100 93 88 Bytes

Die Byteanzahl setzt die ISO 8859-1-Codierung voraus.

$
!¶$`
m`(?<=^(\w+ )*)(?=_.*¶(?<-1>\w+ )*(\w+))
$2
(([a-z])+)(?<-2>_)*(_*)\3|!\D+
$3$1$3

Die Zeichenfolgen werden durch einen Zeilenvorschub getrennt. Wenn noch eine ungerade Anzahl von Unterstrichen übrig ist, steht der fremde hinter dem Wort.

Probieren Sie es online aus!

Erläuterung

Ich denke, dies ist der "Duplicate-Append-Lookback-Match-Add-Center-Ansatz" oder etwas Nahes ...

$
!¶$`

Wir beginnen mit dem Duplizieren der Eingabe (getrennt durch einen !und einen Zeilenvorschub). Der Zweck davon ist, dass wir dann beide Zeilen verarbeiten können, indem wir Wörter aus der nächsten Zeile abrufen (anstatt die zweite Zeile separat behandeln zu müssen).

m`(?<=^(\w+ )*)(?=_.*¶(?<-1>\w+ )*(\w+))
$2

Dies stellt jeder Lücke das richtige Wort voran. Wir beginnen mit dem Zählen der aktuellen Wortposition mit dem Lookbehind (?<=^(\w+ )*)(die Position wird als Gruppentiefe gespeichert 1). Dann wird der Look - Ahead - a) stellt sicher , dass wir am Anfang einer Lücke durch Anpassung sind _, dann springt in die nächste Zeile mit .*¶, passt die richtige Anzahl der Wörter mit (?<-1>\w+ )*in die richtige Position zu bekommen, und dann passt das Wort fand dort mit (\w+)in Gruppe 2.

(([a-z])+)(?<-2>_)*(_*)\3|!\D+
$3$1$3

Diese Phase macht drei Dinge:

  • Es entfernt die Unterstriche, die jeder Wortlänge entsprechen. Dies wird durch Zählen der Wortlänge in Gruppe erfolgt 2mit ([a-z])+und passend dann , dass viele Unterstreichungen (was nie wieder geschrieben).
  • Es verschiebt das Wort in die Mitte der Lücke, indem die Hälfte der verbleibenden Unterstriche mit erfasst (_*)\3und $3$1$3zurückgeschrieben wird.
  • Die doppelte Eingabe wird entfernt, indem sie abgeglichen !\D+und durch nichts ersetzt wird.
Martin Ender
quelle
4

Python 2, 109

def f(a,b):exec"print' '.join([x,y][x<'`'].center(len(x),'_')for x,y in zip(a.split(),b.split()));a,b=b,a;"*2

Die Funktion verwendet zwei Zeichenfolgen als Argumente und druckt die Ausgabe wie in den Beispielen. Es verwendet einen langweiligen Ansatz, bei str.center(width, fillchar)dem der Großteil der Arbeit erledigt wird.

Probieren Sie es online aus .

grc
quelle
1
Ich glaube nicht, dass Sie es brauchen z, es sei denn, mir fehlt etwas. Sie können den Austausch einfach nach dem Drucken und Inline durchführen z.
FryAmTheEggman
@FryAmTheEggman Ja, du hast recht. Danke :)
grc
2

Ruby, 111 109 Zeichen

->l{l.map(&:split).transpose.map{|c|c[m=c[0]<c[1]?0:1]=c[1-m].center c[m].size,?_
c}.transpose.map{|s|s*' '}}

Eingabe: Array von 2 Strings; Ausgabe: Array von 2 Zeichenfolgen.

Probelauf:

2.1.5 :001 > puts ->l{l.map(&:split).transpose.map{|c|c[m=c[0]<c[1]?0:1]=c[1-m].center c[m].size,?_;c}.transpose.map{|s|s*' '}}[[
2.1.5 :002 >       'programming _____________ and code golf',
2.1.5 :003 >       'programming puzzles ______ code ____',
2.1.5 :004 >       ]]
programming ___puzzles___ and code golf
programming puzzles _and__ code golf
Mann bei der Arbeit
quelle
1

JavaScript, 194 185 Bytes

f=(m,n)=>(m=m.split` `,n=n.split` `,G=(x,i,a)=>x[0]!='_'?x:(b=(a?n:m)[i],s=x.length-b.length,(k='_'.repeat(s/2))+b+k+(s%2?'_':'')),H=(e,y)=>e.map((x,i)=>G(x,i,y)).join` `,[H(m,1),H(n)])

Nimmt zwei Zeichenfolgen als Parameter und gibt zwei Zeichenfolgen als Array / Liste aus

entfernt
quelle
1

Mathematica 223

Es muss einen kürzeren Weg geben, dies zu tun.

k=StringLength;m=StringSplit;
g=Partition[Riffle[m@#,m@#2],2]/.{{a_,a_}:> a<>" ",{a_,b_/; StringTake[b,1]=="_"}:> a<>" ",
{a_,b_}:>Table["_",Ceiling[z=(k@a-k@b)/2]]<>b<>""<>Table["_",Floor@z]<>" "}&;
s_~h~t_:={""<>g[s,t],""<>g[t,s]}

Probelauf

h["programming _____________ and code golf", "programming puzzles ______ code ____"]

Geben Sie hier die Bildbeschreibung ein

DavidC
quelle
0

Gema, 208 203 Zeichen

\B=@set{i;0}
<I>=@push{${v;f};$0}@incr{i}
\n=@set{v;s}@set{i;0}
 =
\E=@repeat{$i;@cmps{$f;$s;@set{f;@fill-center{$f;$s}};;@set{s;@fill-center{$s;$f}}}@set{F;$f ${F;}}@set{S;$s ${S;}}@pop{f}@pop{s}}$F\n$S

Nur weil Gema die perfekte Funktion für diese Aufgabe hat : .@fill-center{background;value}

Eingabe: 2 durch Zeilenumbrüche getrennte Zeilen (keine endgültige Zeilenumbruch); Ausgabe: 2 durch Zeilenumbrüche getrennte Zeilen (mit nachgestellten Leerzeichen - scheinen nicht verboten zu sein).

Probelauf:

bash-4.3$ echo -ne 'programming _____________ and code golf\nprogramming puzzles ______ code ____' |
> gema '\B=@set{i;0};<I>=@push{${v;f};$0}@incr{i};\n=@set{v;s}@set{i;0}; =;\E=@repeat{$i;@cmps{$f;$s;@set{f;@fill-center{$f;$s}};;@set{s;@fill-center{$s;$f}}}@set{F;$f ${F;}}@set{S;$s ${S;}}@pop{f}@pop{s}}$F\n$S'
programming ___puzzles___ and code golf 
programming puzzles _and__ code golf 
Mann bei der Arbeit
quelle
0

C 197 Bytes

#define c(w,y)l=strspn(w,"_"),r=strcspn(y," "),memcpy(w+(l-r)/2,y,r),w+=l,y+=r;
main(l,v,w,y,r)char**v,*w,*y;{for(w=v[1],y=v[2];*w;w++,y++)if(*w^*y)if(*w^95)c(y,w)else c(w,y)puts(v[1]);puts(v[2]);}

Ausgabe

$ ./a.out "lorem _____ dolor _____ amet _______________ adipiscing elit mauris dapibus tincidunt _____________________________ accumsan fringilla proin vulputate viverra lorem fermentum dictum" "lorem ipsum ______ sit _______ consectetur _______________ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem ____________________________ dictum"
lorem ipsum dolor _sit_ amet __consectetur__ adipiscing elit mauris dapibus tincidunt ____________metus____________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum dolor_ sit _amet__ consectetur __adipiscing___ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem _________fermentum__________ dictum
Cole Cameron
quelle
0

ES6, 122 Bytes

a=>a.map(s=>s.split` `).map((s,n,a)=>s.map((w,i)=>w<'a'?(l=w.length,t=w+a[n^1][i]+w,t.substr(t.length-l>>1,l)):w).join` `)

Nimmt ein Array mit zwei Zeichenfolgen als einen einzelnen Parameter und gibt ein weiteres Array mit zwei Zeichenfolgen zurück.

Neil
quelle