Mini-golf n. 3 di lunedì: distanza di Anagram


24

Mini-golf del lunedì: una serie di sfide da corto , pubblicate (si spera!) Ogni lunedì.
(Mi dispiace, questo è un po 'in ritardo.)

Sono sicuro che molti di voi hanno sentito parlare della distanza di Levenshtein , un algoritmo per calcolare la distanza tra due stringhe. Bene, questa sfida riguarda l'implementazione di un algoritmo simile della mia invenzione *, chiamato distanza anagramma . La differenza principale è che l'ordine dei personaggi non ha importanza; invece, vengono misurati solo i caratteri che sono univoci per una stringa o per l'altra.

Sfida

L'obiettivo della sfida è scrivere un programma o una funzione che comprenda due stringhe e restituisca la distanza anagramma tra di esse. Il modo principale per farlo è utilizzare la seguente logica:

  1. Converti entrambe le stringhe in minuscolo e (facoltativamente) ordina i caratteri di ciascuno in ordine alfabetico.
  2. Mentre le stringhe contengono almeno un carattere uguale, rimuovi la prima istanza di questo carattere da ogni stringa.
  3. Aggiungi le lunghezze delle stringhe rimanenti e restituisce / emette il risultato.

Esempio

Se gli ingressi sono:

Hello, world!
Code golf!

Quindi, in minuscolo e ordinati, questi diventano: (secondo l'ordinamento predefinito di JS; notare gli spazi iniziali)

 !,dehllloorw
 !cdefgloo

Rimuovendo tutti i caratteri che si trovano in entrambe le stringhe, finiamo con:

,hllrw
cfg

Pertanto, la distanza anagramma tra le due stringhe originali = 6 + 3 = 9.

Dettagli

  • Le stringhe possono essere prese in qualsiasi formato ragionevole.
  • Le stringhe saranno costituite solo da ASCII stampabile.
  • Le stringhe stesse non conterranno spazi bianchi diversi dagli spazi regolari. (Nessuna scheda, newline, ecc.)
  • Non è necessario utilizzare questo algoritmo esatto, purché i risultati siano gli stessi.

Casi test

Ingresso 1:

Hello, world!
Code golf!

Uscita 1:

9

Ingresso 2:

12345 This is some text.
.txet emos si sihT 54321

Uscita 2:

0

Ingresso 3:

All unique characters here!
Bdfgjkmopvwxyz?

Uscita 3:

42

Ingresso 4:

This is not exactly like Levenshtein distance,
but you'll notice it is quite similar.

Uscita 4:

30

Ingresso 5:

all lowercase.
ALL UPPERCASE!

Uscita 5:

8

punteggio

Questo è , quindi vince il codice valido più breve in byte. Tiebreaker va all'invio che ha raggiunto per primo il numero di byte finale. Il vincitore verrà scelto lunedì prossimo, 12 ottobre. Buona fortuna!

Modifica: Congratulazioni al vincitore, @isaacg, usando Pyth (di nuovo) per un sorprendente 12 byte!

* Se questo algoritmo è stato utilizzato altrove e / o è stato assegnato un altro nome, per favore fatemi sapere! Non sono riuscito a trovarlo con una ricerca di 20 minuti.


Descrivere l'attività come "scrivere un programma [...] che [fa cose] usando la seguente logica" per aggiungere successivamente "Non è necessario utilizzare questo algoritmo esatto [...]" è un po 'contraddittoria.
Édouard,

@ Édouard True; Grazie per la segnalazione. Credo che ora sia meglio.
ETHproductions

È già di nuovo martedì. ;)
Martin Ender,

@ MartinBüttner È difficile scrivere una sfida mentre sei in viaggio senza wi-fi. ;) Non preoccuparti, ne avrò uno nuovo pronto tra poco.
ETHproductions

Risposte:


14

Pyth, 12 byte

ls.-M.prR0.z

Suite di test

L'operazione in questione è equivalente all'operatore di sottrazione bagwise di Pyth .-, applicato in entrambe le direzioni. Potresti chiamarlo bagwise xor, suppongo.

La soluzione è:

.z: ottiene l'input come elenco di 2 stringhe.

rR0: converti entrambi in minuscolo.

.p: Forma tutte le permutazioni, cioè normale e invertita.

.-M: Mappa l' .-operazione su ogni ordine.

s: Concatena i risultati.

l: Stampa la lunghezza.


E ho pensato che tutte le risposte potrebbero essere troppo lunghe ... Ben fatto!
ETHproductions

8

JavaScript (ES7), 92 byte

Definisce una funzione anonima.

Per eseguire il test, esegui il frammento di seguito. È possibile modificare il codice e fare clic su "Test" per confrontare il suo output con l'originale. (Lascia un commento se trovi un miglioramento!) L'input è come "Hello, world!", "Code golf!"nella casella di input.

Grazie a @ETHproductions per aver salvato 6 byte!


(a,b)=>[for(v of a[t="toLowerCase"]())if((b=b[t]())==(b=b.replace(v,"")))v][l="length"]+b[l]
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML+='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{var evalResult=eval(code);if(typeof evalResult=="function"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

Ulteriori informazioni sulla suite di test


Come funziona

//Define function w/ paramters a, b
(a,b)=>
     //lowercase a
     //for each character v in a:
     [for(v of a[t="toLowerCase"]())
          //lowercase b
          //remove the first instance of v in b
          //if b before removal equals b after removal (if nothing was removed):
          if((b=b[t]())==(b=b.replace(v,"")))
               //keep v in the array of a's values to keep
               v]
     //get the length of the computed array
     [l="length"]
     //add b's length
     +b[l]
     //implicitly return the sum

Ho lavorato su una risposta ES6 basata su array per un'ora e sono riuscito a portarlo solo a 122. Sembra che stavo guardando nella direzione sbagliata! +1
ETHproductions

A proposito, si potrebbe sostituire .join("")+bcon .join``+bsenza alcun effetto.
ETHproductions

1
Wow, dove diavolo hai preso quella suite di test? È brillante! Vorrei poter fare +1 altre tre o quattro volte ....
ETHproductions

@ETHproductions Grazie! : DI ha creato personalmente la suite di test. Dai un'occhiata al mio meta post!
jrich

Ho fatto +1 laggiù, spero che compensi per non essere in grado di fare +5 qui. ;)
ETHproductions

6

CJam, 23 19 byte

2{'¡,lelfe=}*.-:z:+

Provalo online nell'interprete CJam .

Come funziona

2{         }*        Do the following twice:
  '¡,                  Push the string of the first 161 Unicode charcters.
     lel               Read a line from STDIN and convert it to lowercase.
        fe=            Count the number of occurrences of each of the 160
                       characters in the lowercased line.
             .-      Vectorized subtraction; push the differences of the
                     occurrences of all 161 characters.
               :z    Apply absolute value to each difference.
                 :+  Push the sum of all results.

4

Ruby, 62

#!ruby -naF|
gets
p$F.count{|c|!$_.sub!(/#{Regexp.escape c}/i){}}+~/$/

Deve esserci un modo migliore.

Modifica: 57 caratteri grazie a iamnotmaynard che studia un percorso in cui ero troppo pigro.

#!ruby -naF|
gets.upcase!
p$F.count{|c|!$_.sub!(c.upcase){}}+~/$/

subpuò prendere le stringhe. Non potresti usare al c.downcaseposto di /#{Regexp.escape c}/i?
Ripristina Monica iamnotmaynard il

Dovrei sottovalutare entrambe le stringhe (o upcase, equivalentemente.)
histocrat

Ah certo. (Anche se mi sembra che farlo ti risparmierebbe ancora un paio di byte.)
Reinstalla Monica iamnotmaynard il

4

Python, 90 87 81 80 79 byte

lambda a,b,s=str.lower:sum(abs(s(a).count(c)-s(b).count(c)))for c in{*s(a+b)}))

Python <3.5 versione, 80 byte

lambda a,b,s=str.lower:sum(abs(s(a).count(c)-s(b).count(c))for c in set(s(a+b)))

Spiegazione

Per ogni carattere in a o b, conta il numero di occorrenze in ciascuna stringa e aggiungi la differenza (positiva).

Modifica: rileggi le regole, le funzioni anonime realizzate sono accettabili, migliora la risposta eliminando raw_input. Primo golf, per favore sii gentile!

Grazie a sp3000 per il miglioramento della ridefinizione di str.lower e per farmi capire che la stampa non era necessaria. Anche spazi. Ancora imparando.

Usando python> = 3.5, esiste un modo più breve di definire i set, quindi un byte può essere salvato rispetto alle versioni precedenti.


3

Retina, 40 20 byte

20 byte salvati grazie a Martin Büttner.

Inserire ogni riga nel proprio file e sostituirla \ncon una nuova riga letterale.

+i`(.)(.*\n.*)\1
$2
.

2

pb , 648 byte

^w[B!0]{t[B]vb[T]^>}vb[-1]w[X!0]{<t[64]w[T!0]{w[B!0]{b[B-1]v}^[Y]t[T-1]}}w[B!-1]{w[B=0]{b[27]}t[26]w[T!0]{w[B!0]{b[B-1]v}^[Y]t[T-1]}>}b[0]w[X!0]{<w[B!0]{b[1]v}^[Y]w[B=0]{b[32]}w[B=1]{b[0]}}^w[B!0]{t[B]vb[B+T]^>}vb[1]<w[B!9]{t[B]b[0]vv<[X]w[B!0]{>}b[T]^^<[X]w[B!0]{>}<}b[0]<w[X!-1]{t[B]vb[1]^w[B!1]{>}vvw[X!-1]{w[B=T]{b[0]<[X]^w[B!1]{>}^b[0]vt[2]}<}^[Y]vw[B!1]{>}b[0]^<}t[0]w[B!1]{w[B!0]{t[T+1]b[0]}>}b[0]vvw[X!-1]{w[B!0]{t[T+1]b[0]}<}>b[11]^b[T]w[B!0]{vw[B!11]{>}t[B]b[0]>b[T]<[X]^t[B]b[0]vw[B!11]{>}<w[T!0]{t[T-1]b[B+1]w[B=11]{b[0]^<[X]b[B+1]vw[B!11]{>}<}}^<[X]}vw[B!11]{b[B+48]>}b[0]<w[B!0]{w[B!0]{>}<t[B]^^<[X]w[B!0]{>}b[T]<[X]vvw[B!0]{>}<b[0]<}

Accetta l'input con un carattere di tabulazione che separa le due stringhe.

Questo era un doozy. In realtà implementare l'algoritmo non era la parte difficile, che è venuto relativamente facilmente. Ma ho dovuto fare due cose che sono difficili da fare in pb: insensibilità al caso e itoa. Mi è capitato di avere un programma per la conversione in minuscolo che giaceva in giro (anch'esso lungo 211 byte) e tutto il resto è stato fissato alla fine per fare il lavoro per questa sfida in particolare.

Puoi guardare questo programma in esecuzione su YouTube! Ci sono un paio di cose che dovresti tenere a mente se lo fai:

  • Questa versione del programma è leggermente modificata, con un peso di 650 byte. L'unica differenza è che 255 viene utilizzato come valore di flag invece di -1, poiché il tentativo di stampa chr(-1)provoca l'interruzione dell'interprete durante l'esecuzione in modalità orologio.
  • L'ingresso in quel video è Hello, world!e Code golf.. Questo è leggermente diverso da uno degli input di esempio nella sfida; L'ho usato perché era corto ma l'ho modificato in modo che l'output corretto fosse 10 invece di 9. Questo è solo per mostrare che il numero viene stampato correttamente anche se è composto da più cifre, il che è difficile in pb.
  • L'interprete è terribile, e mostra qui. In particolare, il carattere di tabulazione elimina la spaziatura in modo che le cose non siano allineate per grandi parti del video, ogni volta che un byte è impostato su 10 mostra un'interruzione di linea anche se la lingua lo considera ancora una "linea", e il fatto che sposta semplicemente il cursore all'inizio invece di cancellare lo schermo significa che occasionalmente ci sono un certo numero di personaggi nel video che non sono nemmeno realmente lì, che non sono mai andati via da quando erano lì. Ci sono alcune protezioni contro questo in PBI, ma il fattochr(10)non è gestito correttamente li rende ampiamente inutili qui. Detto questo, penso che sia quasi bello da guardare. È un enorme casino di codice orribile che interpreta altro codice orribile, pezzi di esso si rompono davanti ai tuoi occhi, eppure tutto funziona quanto basta per ottenere la risposta giusta. Sembra che la spazzatura venga stampata ma se guardi abbastanza attentamente con la conoscenza della fonte puoi capire cosa sta facendo e perché in qualsiasi momento. Mi sento Cypher quando guardo questo video:I... I don’t even see the code. All I see is blonde, brunette, red-head.

Senza ulteriori indugi, ecco il codice ungolfed.

### UNTIL FURTHER NOTICE, ALL CODE YOU SEE HERE   ###
### IS JUST A SIMPLE LOWERCASE PROGRAM. ALL INPUT ###
### IS PRINTED UNALTERED UNLESS ITS ASCII CODE IS ###
### IN [65, 90], IN WHICH CASE IT IS PRINTED WITH ###
### 32 ADDED TO IT.                               ###

^w[B!0]{t[B]vb[T]^>}    # Copy entire input to Y=0
                        # (If the program ended here, it would be cat!)
vb[-1]                  # Leave a flag at the end of the copy (important later)

# Next, this program will set each of those bytes to 0 or 32, then add the input again.
# A byte needs to be set to 32 iff it's in [65, 90].
# pb can't test > or <, only == and !=.
# A workaround:

# Set each byte to max((byte - 64), 0)



w[X!0]{<        # For each byte:
    t[64]         # Set T to 64 as a loop variable
    w[T!0]{       # While T != 0:
        w[B!0]{     # While the current byte not 0:
            b[B-1]v   # Subtract one from the current cell, then go down one
                      # (guaranteed to be 0 and kill the loop)
        }
        ^[Y]        # Brush is at Y=0 or Y=1 and needs to be at Y=0.
                    # ^[Y] always brings brush to Y=0
        t[T-1]      # T--
    }
}

# Bytes that are currently 0 need to be 0.
# Bytes that are currently in [27, inf) need to be 0.
# Bytes in [1, 26] need to be 32.

# Set bytes that are equal to 0 to 27
# The only groups that have to be worried about are >26 and =<26.

# Then set each byte to max((byte - 26), 0)

w[B!-1]{         # Until we hit the flag:
    w[B=0]{b[27]}   # Set any 0 bytes to 27
    t[26]           # T as loop variable again
    w[T!0]{         # While T != 0:
        w[B!0]{       # While the current byte not 0:
            b[B-1]v     # Subtract one from the current cell, then go down one
                        # (guaranteed to be 0 and kill the loop)
        }
        ^[Y]          # Brush is at Y=0 or Y=1 and needs to be at Y=0.
                      # ^[Y] always brings brush to Y=0
        t[T-1]        # T--
    }
>}
b[0]              # Clear the flag

# Set bytes that are equal to 0 to 32
# All others to 0

w[X!0]{<          # For each byte:
    w[B!0]{       # While the current byte not 0:
        b[1]v       # Set it to 1, then go down one
                    # (guaranteed to be 0 and kill the loop)
    }
    ^[Y]          # Back to Y=0 no matter what
    w[B=0]{b[32]} # Set 0 bytes to 32
    w[B=1]{b[0]}  # Set 1 bytes to 0
}

# Any byte that had a capital letter is now 32. All others are 0.
# Add the original values to the current values to finish.

^w[B!0]{          # For each byte OF ORIGINAL INPUT:
    t[B]vb[B+T]^>   # Add it to the space below
}

### ABOVE IS THE ENTIRE LOWERCASE PROGRAM. THE    ###
### REST OF THE CODE IMPLEMENTS THE ALGORITHM.    ###

vb[1]            # Leave a flag after the end, guaranteed to be further right
                 # than anything else

<w[B!9]{         # Starting from the end, until hitting a tab:
    t[B]b[0]        # Store the last byte and erase it
    vv<[X]          # Go down two columns and all the way to the left
    w[B!0]{>}       # Go right until reaching an empty space
    b[T]            # Print the stored byte
    ^^<[X]w[B!0]{>} # Go back to the end of the first line
    <
}

b[0]              # Erase the tab
<w[X!-1]{         # For each byte in the first line:
    t[B]            # Store that byte
    vb[1]           # Mark that byte to be found later
    ^w[B!1]{>}      # Find the flag at the end
    vvw[X!-1]{      # For everything in the other line:
        w[B=T]{       # If the current byte is the same as the saved byte:
            b[0]        # Set it to 0
            <[X]^       # Go to the beginning of line 2
            w[B!1]{>}   # Find the marker for where the program is working in line 1
            ^b[0]v      # Set that byte that the program is working on to 0
            t[2]        # Stay on line 2 and start looking for a 2 (will never appear)
                        # (If this block was entered, it basically breaks the outer loop.)
        }
        <
    }
    ^[Y]v           # Ensure that the brush is on Y=1
    w[B!1]{>}       # Find the marker for where the program is working in line 1
    b[0]^<          # Erase the marker and start working on the next byte
}

t[0]              # Set T to 0. It's going to be used for counting the remaining bytes.

w[B!1]{           # Until hitting the flag at the very right:
    w[B!0]{         # If the current byte is not 0:
        t[T+1]        # Add 1 to T
        b[0]          # Set the current byte to 0
    }
    >
}
b[0]              # Clear the flag

vvw[X!-1]{        # Same as above, but for Y=2
    w[B!0]{
        t[T+1]
        b[0]
    }
    <
}

# T now contains the number that needs to be printed!!
# Now, to print out a number in decimal...

>b[11]            # A flag that shows the end of the number
                  # (so 0 digits aren't confused for other empty spaces on the canvas)
^b[T]             # The number to be converted to digits
w[B!0]{           # While the number to be converted is not 0:
    vw[B!11]{>}     # Go to the flag
    t[B]b[0]>b[T]   # Move it right
    <[X]^t[B]b[0]   # Store the number to be converted to digits to T and clear its space on the canvas
    vw[B!11]{>}<    # Go to the left of the flag
    w[T!0]{         # While T is not 0:
        t[T-1]        # T--
        b[B+1]        # B++
        w[B=11]{      # If B is 10:
            b[0]        # Set it back to 0
            ^<[X]b[B+1]   # Add 1 to a counter to be converted after
            vw[B!11]{>}<  # Go back to continue converting T
        }
    }
^<[X]}

vw[B!11]{         # Add 48 to all digits to get correct ASCII value
    b[B+48]>
}

b[0]              # Clear the flag value, 0s now appear as 48 instead of 0 so it is unnecessary

<w[B!0]{          # While there are digits on Y=2:
    w[B!0]{>}<      # Go to the last one
    t[B]            # Save it to T
    ^^<[X]          # Go to (0, 0)
    w[B!0]{>}       # Go right until finding an empty space
    b[T]            # Print the digit in T
    <[X]vvw[B!0]{>} # Go to the end of Y=2
    <b[0]           # Erase it
    <               # Repeat until finished. :)
}

2

C ++ 199 byte

Utilizza un array per memorizzare il conteggio di ciascun carattere nella prima stringa, minis il conteggio nella seconda stringa. Successivamente trova la somma dei valori assoluti degli elementi dell'array: questa è la distanza.

golfed:

#define L(c) c<91&c>64?c+32:c
int d(char*a,char*b){int l[128];int i=128,s=0;for(;i-->0;)l[i]=0;for(;a[++i];)l[L(a[i])]++;for(i=-1;b[++i];)l[L(b[i])]--;for(i=0;++i<128;)s+=i[l]>0?i[l]:-i[l];return s;}

Ungolfed:

#define L(c) (c<='Z' && c>='A' ? c+'a'-'A':c)
//convert to lower case
int dist(char a[],char b[]){
  int l[128];
  int i = 128, s = 0;

  for(;i-->0;)
    l[i]=0;

  for(;a[++i]!='\0';)
    l[L(a[i])]++;

  for(i=-1;b[++i]!='\0';)
    l[L(b[i])]--;

  for(i=0;++i<128;)
    s+=i[l]>0?i[l]:-i[l];

  return s;
}

1

PowerShell, 79 byte

param($a,$b)$a=[char[]]$a.ToLower();$b=[char[]]$b.ToLower();(diff $a $b).Length

Quasi lo stesso identico codice della mia risposta su Anagram Code Golf ... ma ... mi sto comportando in modo strano se mi stacco -eq0da quella risposta, quindi mi ritrovo a dover ricorrere esplicitamente .ToLower()e rifondere al di fuori della paramdichiarazione. +

Spiegazione anche (principalmente) copiata da quella risposta - Prende i due input di stringa, li rende minuscoli e li rilancia come char-array. La difffunzione (un alias per Compare-Object) accetta i due array e restituisce elementi diversi tra i due. Lo sfruttiamo ri-lanciando il ritorno come un array con (), e quindi controllandone la lunghezza.

+ Per esempio, mi è stato sempre risultati falsi con param([char[]]$a,[char[]]$b)(diff $a $b).lengthil all lowercase./ ALL UPPERCASE!test. Se separassi manualmente le matrici (ad esempio, funzionasse (diff ('a','l','l'...), funzionava bene, ma falliva ogni volta che si verificava una sovrapposizione maiuscola / minuscola con il casting. Tutto ciò che posso leggere nella documentazione afferma che non diffdistingue tra maiuscole e minuscole per impostazione predefinita, quindi ... scrollare le spalle ???


Molto strano. Non è necessario per nessuno degli altri casi (anche con diversa sensibilità al maiuscolo / minuscolo).
Jonathan Leech-Pepin,

1

Bash, 68 67 byte

f()(fold -w1<<<"$1"|sort)
diff -i <(f "$1") <(f "$2")|grep -c ^.\ 

Penso che funzioni. Nota lo spazio finale sulla seconda riga.

Casi test

$ ./anagram "Hello, world!" "Code golf!"
9
$ ./anagram "12345 This is some text." ".txet emos si sihT 54321"
0
$ ./anagram "All unique characters here!" "Bdfgjkmopvwxyz?"
42
$ ./anagram "This is not exactly like Levenshtein distance," "but you'll notice it is quite similar."
30
$ ./anagram "all lowercase." "ALL UPPERCASE!"
8

1

Perl, 52 46 byte + 3 switch (a, F, n) = 55 49 byte

# 49 bytes (prefix 'x' to all characters so that values() could be removed)
perl -naF -E 'END{$c+=abs for%a;say$c}$a{x.lc}+=2*$.-3 for@F'

# 55 bytes
perl -naF -E 'END{$c+=abs for values%a;say$c}$a{+lc}+=2*$.-3 for@F'

Riceve input da STDIN con le stringhe di input nelle proprie righe, terminate da EOF.

interruttori:

-aF splits each input line into characters and stores this into @F
-n  loop over all input lines
-E  Execute the script from the next arg

Codice:

# %a is the hash counting the occurances of the lowercase characters
# $. has the line number. Thus, 2*$.-3 is -1 for line 1 and +1 for line 2
$a{+lc}+=2*$.-3 for @F

# In the end (assuming 2 lines have been read), sum up the absolute values
# from the hash %a. Note that if a character occured more times in string 1
# its value be negative, if more in string 2 then positive, otherwise 0.
END {
    $c+=abs for values %a;
    say $c
}

1

Utilità Bash + GNU, 53

S(){ sed 's/./\L&\n/g'|sort;};S>1;S|comm -3 1 -|wc -l

sedsi trasforma in minuscolo e divide la stringa in righe per sort. Dato che dobbiamo farlo due volte, lo inserisco in una funzione. comm3 -3filtra le righe pertinenti e wc -lproduce il numero.

L'ingresso è via STDIN; poiché due comandi vengono letti in sequenza, è necessario inviare EOF(Ctrl-D) due volte, tra le stringhe e alla fine. Sovrascrive il file 1, se presente.


1

Matlab, 91 byte

function r=f(s,t)
s=lower(s);t=lower(t);u=unique([s t]);r=sum(abs(histc(s,u)-histc(t,u)));

Provalo online .

Funziona come segue:

  1. Converte le stringhe in lettere minuscole.
  2. Trova insieme i caratteri unici delle due stringhe. Cioè, determina tutti i caratteri che appaiono mai nelle stringhe.
  3. Calcola l' istogramma di ogni stringa. Cioè, per ogni stringa trova quante volte appare ciascuno dei caratteri ottenuti nel passaggio 2.
  4. Sottrae gli istogrammi e assume il valore assoluto delle differenze. Ciò rappresenta quante volte un carattere appare in una stringa più che nell'altra.
  5. Il risultato è la somma di quelle differenze assolute.

Sembra troppo lungo-- sei sicuro che sia ottimale?
lirtosiast

@ThomasKwa No, per niente :-)
Luis Mendo,


0

F #, 134 126 byte

let g=Seq.countBy Char.ToLower>>List.ofSeq
let f a b=g a@g b|>Seq.groupBy fst|>Seq.sumBy(snd>>Seq.map snd>>Seq.reduce(-)>>abs)

Spiegazione :

  1. Contare il numero di volte in cui ciascun carattere (minuscolo) appare ae bseparatamente.
  2. Raggruppa i conteggi in base al loro carattere comune
  3. Ridurre ciascun gruppo con l' -operatore, che ha il seguente effetto:

    • Se viene trovato un solo valore (ovvero il carattere è apparso in un solo input), quel valore viene restituito.
    • Se vengono trovati due valori (ovvero il carattere è apparso in entrambi gli input) sottrarre il secondo valore dal primo.
  4. Somma il valore assoluto dei valori dal passaggio precedente.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.