Lundi Mini-Golf # 3: distance Anagram

24

Monday Mini-Golf: Une série de courts défis de , affichés (espérons-le!) Tous les lundis.
(Désolé celui-ci est un peu en retard.)

Je suis sûr que la plupart d'entre vous ont entendu parler de la distance de Levenshtein , un algorithme pour calculer la distance entre deux chaînes. Eh bien, ce défi consiste à implémenter un algorithme similaire de ma propre invention *, appelé distance anagramme . La principale différence est que l'ordre des caractères n'a pas d'importance; au lieu de cela, seuls les caractères uniques à une chaîne ou à l'autre sont mesurés.

Défi

Le but du défi est d'écrire un programme ou une fonction qui prend deux chaînes et renvoie la distance entre elles entre les anagrammes. La principale façon de procéder consiste à utiliser la logique suivante:

  1. Convertissez les deux chaînes en minuscules et (facultativement) triez les caractères de chacun par ordre alphabétique.
  2. Bien que les chaînes contiennent au moins un caractère égal, supprimez la première instance de ce caractère de chaque chaîne.
  3. Ajoutez les longueurs des chaînes restantes et retournez / sortez le résultat.

Exemple

Si les entrées sont:

Hello, world!
Code golf!

Ensuite, en minuscules et triés, ceux-ci deviennent: (par le tri par défaut de JS; notez les espaces de tête)

 !,dehllloorw
 !cdefgloo

En supprimant tous les caractères des deux chaînes, nous nous retrouvons avec:

,hllrw
cfg

Ainsi, la distance anagramme entre les deux chaînes originales = 6 + 3 = 9.

Détails

  • Les chaînes peuvent être prises dans n'importe quel format raisonnable.
  • Les chaînes seront uniquement constituées d'ASCII imprimables.
  • Les chaînes elles-mêmes ne contiendront aucun espace autre que des espaces réguliers. (Pas d'onglets, de nouvelles lignes, etc.)
  • Vous n'avez pas besoin d'utiliser cet algorithme exact, tant que les résultats sont les mêmes.

Cas de test

Entrée 1:

Hello, world!
Code golf!

Sortie 1:

9

Entrée 2:

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

Sortie 2:

0

Entrée 3:

All unique characters here!
Bdfgjkmopvwxyz?

Sortie 3:

42

Entrée 4:

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

Sortie 4:

30

Entrée 5:

all lowercase.
ALL UPPERCASE!

Résultat 5:

8

Notation

Il s'agit de , donc le code valide le plus court en octets l'emporte. Tiebreaker passe à la soumission qui a atteint son nombre d'octets final en premier. Le gagnant sera choisi lundi 12 octobre prochain. Bonne chance!

Edit: Félicitations au gagnant, @isaacg, en utilisant (à nouveau) Pyth pour un incroyable 12 octets!

* Si cet algorithme a été utilisé ailleurs et / ou a reçu un autre nom, veuillez me le faire savoir! Je n'ai pas pu le trouver avec une recherche de 20 minutes.

ETHproductions
la source
Décrire la tâche comme «écrire un programme […] qui [fait des trucs] en utilisant la logique suivante» pour ajouter plus tard «Vous n'avez pas besoin d'utiliser cet algorithme exact […]» est un peu contradictoire.
Édouard
@ Édouard True; Merci d'avoir fait remarquer cela. Je crois que c'est mieux maintenant.
ETHproductions
C'est déjà mardi à nouveau. ;)
Martin Ender
@ MartinBüttner C'est un peu difficile d'écrire un défi pendant que vous êtes sur la route sans Wi-Fi. ;) Ne vous inquiétez pas, j'en aurai un nouveau prêt dans un petit moment.
ETHproductions

Réponses:

14

Pyth, 12 octets

ls.-M.prR0.z

Suite de tests

L'opération en question est équivalente à l'opérateur de soustraction par sac de Pyth .-, appliqué dans les deux directions. Vous pourriez l'appeler bagwise xor, je suppose.

La solution est:

.z: obtenir une entrée sous forme de liste de 2 chaînes.

rR0: convertit les deux en minuscules.

.p: Forme toutes les permutations, c'est-à-dire normales et inversées.

.-M: Mappez l' .-opération sur chaque commande.

s: Concaténer les résultats.

l: Imprimer la longueur.

isaacg
la source
Et j'ai pensé que toutes les réponses pourraient être trop longues ... Bravo!
ETHproductions
8

JavaScript (ES7), 92 octets

Définit une fonction anonyme.

Pour tester, exécutez l'extrait ci-dessous. Vous pouvez modifier le code et cliquer sur «Test» pour comparer sa sortie avec l'original. (Laissez un commentaire si vous trouvez une amélioration!) L'entrée est comme "Hello, world!", "Code golf!"dans la zone de saisie.

Merci à @ETHproductions pour avoir économisé 6 octets!


(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>

En savoir plus sur la suite de tests


Comment ça marche

//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
jrich
la source
Je travaillais sur une réponse ES6 basée sur une baie depuis une heure, et je n'avais pu la ramener qu'à 122. On dirait que je regardais dans la mauvaise direction! +1
ETHproductions
BTW, vous pouvez remplacer .join("")+bavec .join``+bsans effet.
ETHproductions
1
Wow, où diable avez-vous obtenu cette suite de tests? C'est brilliant! J'aurais aimé pouvoir +1 trois ou quatre fois de plus ....
ETHproductions
@ETHproductions Merci! : DI a fait la suite de tests moi-même, en fait. Consultez mon meta post!
jrich
J'ai + 1'ed là-bas, j'espère que cela compense de ne pas pouvoir +5 ici. ;)
ETHproductions
6

CJam, 23 19 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça marche

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.
Dennis
la source
4

Rubis, 62

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

Il doit y avoir une meilleure façon.

Edit: 57 caractères grâce à iamnotmaynard enquêtant sur un chemin que j'étais trop paresseux.

#!ruby -naF|
gets.upcase!
p$F.count{|c|!$_.sub!(c.upcase){}}+~/$/
histocrate
la source
subpeut prendre des chaînes. Ne pourriez-vous pas utiliser à la c.downcaseplace de /#{Regexp.escape c}/i?
Rétablir Monica iamnotmaynard
Je devrais downcase les deux cordes (ou upcase, de manière équivalente.)
histocrate
Ah, bien sûr. (Bien qu'il me semble que cela vous ferait encore économiser quelques octets.)
Réinstallez Monica iamnotmaynard
4

Python, 90 87 81 80 79 octets

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

Version Python <3.5, 80 octets

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

Explication

Pour chaque caractère dans a ou b, comptez le nombre d'occurrences dans chaque chaîne et ajoutez la différence (positive).

Edit: relisez les règles, les fonctions anonymes réalisées sont acceptables, réponse améliorée en supprimant raw_input. Premier golf, soyez doux!

Merci à sp3000 pour l'amélioration de la redéfinition de str.lower et pour me faire réaliser que l'impression n'était pas nécessaire. Espaces également. Encore à apprendre.

En utilisant python> = 3.5, il existe un moyen plus court de définir des ensembles, donc un octet peut être enregistré par rapport aux versions précédentes.

Mego
la source
3

Rétine, 40 20 octets

20 octets économisés grâce à Martin Büttner.

Placez chaque ligne dans son propre fichier et remplacez la \npar une nouvelle ligne littérale.

+i`(.)(.*\n.*)\1
$2
.
Le numéro un
la source
2

pb , 648 octets

^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]<}

Prend la saisie avec un caractère de tabulation séparant les deux chaînes.

Celui-ci était un doozy. En fait, la mise en œuvre de l'algorithme n'était pas la partie difficile, cela est venu assez facilement. Mais j'ai dû faire deux choses qui sont difficiles à faire en pb: Insensibilité à la casse et itoa. Il se trouve que j'avais un programme de conversion en minuscules qui traîne (lui-même 211 octets de long) et tout le reste a été cloué à la fin pour faire le travail spécifiquement pour ce défi.

Vous pouvez regarder ce programme exécuté sur YouTube! Il y a quelques choses que vous devez garder à l'esprit si vous le faites:

  • Cette version du programme est légèrement modifiée, pesant 650 octets. La seule différence est que 255 est utilisé comme valeur d'indicateur au lieu de -1, car la tentative d'impression chr(-1)bloque l'interpréteur lors de l'exécution en mode veille.
  • L'entrée dans cette vidéo est Hello, world!et Code golf.. Ceci est légèrement différent de l'un des exemples d'intrants du défi; Je l'ai utilisé parce qu'il était court mais je l'ai modifié pour que la sortie correcte soit 10 au lieu de 9. C'est juste pour montrer que le numéro est imprimé correctement même s'il s'agit de plusieurs chiffres, ce qui est difficile en pb.
  • L'interprète est horrible, et ça se voit ici. En particulier, le caractère de tabulation supprime l'espacement afin que les choses ne soient pas alignées pour de grandes parties de la vidéo, chaque fois qu'un octet est défini sur 10, il montre un saut de ligne même si la langue le considère toujours comme une "ligne", et le fait qu'il déplace simplement le curseur au début au lieu d'effacer l'écran signifie qu'il y a parfois un certain nombre de personnages dans la vidéo qui ne sont même pas vraiment là, ils ne se sont jamais éloignés de quand ils étaient là. Il existe des protections contre cela en pbi mais le fait quechr(10)n'est pas géré correctement les rend largement inutiles ici. Cela étant dit, je pense que c'est presque assez beau à regarder. C'est un énorme gâchis de code horrible interprétant un autre code horrible, des morceaux se décomposant devant vos yeux, et pourtant tout fonctionne juste assez pour obtenir la bonne réponse. Il semble que les ordures soient imprimées, mais si vous regardez assez attentivement avec la connaissance de la source, vous pouvez comprendre ce qu'il fait et pourquoi à tout moment. Je me sens comme Cypher quand je regarde cette vidéo:I... I don’t even see the code. All I see is blonde, brunette, red-head.

Sans plus tarder, voici le code non golfé.

### 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. :)
}
métro monorail
la source
2

C ++ 199 octets

Utilise un tableau pour stocker le nombre de chaque caractère dans la première chaîne, minis le nombre dans la deuxième chaîne. Ensuite, il trouve la somme des valeurs absolues des éléments du tableau: c'est la distance.

Golfé:

#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;}

Non golfé:

#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;
}
MegaTom
la source
1

PowerShell, 79 octets

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

Presque le même code exact que ma réponse sur Anagram Code Golf ... mais ... Je reçois un comportement étrange si je coupe juste la -eq0réponse, donc j'ai fini par devoir explicitement .ToLower()et refondre en dehors de la paramdéclaration. +

Explication également (principalement) copiée à partir de cette réponse - Prend les deux entrées de chaîne, les rend en minuscules et les retransmet en tant que tableaux de caractères. La difffonction (un alias pour Compare-Object) prend les deux tableaux et renvoie des éléments différents entre les deux. Nous tirons parti de cela en recréant le retour sous forme de tableau avec (), puis en vérifiant sa longueur.

+ Par exemple, j'obtenais de faux résultats avec param([char[]]$a,[char[]]$b)(diff $a $b).lengthle all lowercase./ ALL UPPERCASE!test. Si je séparais manuellement les tableaux (par exemple, courais (diff ('a','l','l'...), cela fonctionnait bien, mais échouait à chaque fois qu'il y avait un chevauchement majuscule / minuscule avec le casting. Tout ce que je peux lire sur la documentation diffest insensible à la casse par défaut, alors ... hausser les épaules ???

AdmBorkBork
la source
Très étrange. Il n'est nécessaire pour aucun des autres cas (même avec une sensibilité à la casse différente).
Jonathan Leech-Pepin
1

Bash, 68 67 octets

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

Je pense que cela fonctionne. Notez l'espace de fin sur la deuxième ligne.

Cas de 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
Dennis
la source
1

Perl, 52 46 octets + 3 commutateurs (a, F, n) = 55 49 octets

# 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'

Prend l'entrée de STDIN avec les chaînes d'entrée dans leurs propres lignes, terminées par EOF.

Commutateurs:

-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

Code:

# %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
}
svsd
la source
1

Utilitaires Bash + GNU, 53

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

sedse transforme en minuscules et divise la chaîne en lignes pour sort. Comme nous devons le faire deux fois, je l'ai mis dans une fonction. comm3 -3filtre les lignes pertinentes et wc -lproduit le nombre.

L'entrée se fait via STDIN; puisque deux commandes sont lues séquentiellement, vous devez envoyer EOF(Ctrl-D) deux fois, entre les chaînes et à la fin. Remplace le fichier 1, le cas échéant.

xebtl
la source
1

Matlab, 91 octets

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

Essayez-le en ligne .

Cela fonctionne comme suit:

  1. Convertit les chaînes en minuscules.
  2. Trouve les caractères uniques des deux chaînes ensemble. Autrement dit, détermine tous les caractères qui apparaissent dans les chaînes.
  3. Calcule l' histogramme de chaque chaîne. Autrement dit, pour chaque chaîne trouve combien de fois chacun des caractères obtenus à l'étape 2 apparaît.
  4. Soustrait les histogrammes et prend la valeur absolue des différences. Cela représente le nombre de fois qu'un caractère apparaît dans une chaîne de plus que dans l'autre.
  5. Le résultat est la somme de ces différences absolues.
Luis Mendo
la source
Cela semble beaucoup trop long - êtes-vous sûr que c'est optimal?
lirtosiast
@ThomasKwa Non, pas du tout :-)
Luis Mendo
0

F #, 134 126 octets

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)

Explication :

  1. Comptez le nombre de fois que chaque caractère (en minuscule) apparaît dans aet bséparément.
  2. Regrouper les dénombrements par leur caractère commun
  3. Réduisez chaque groupe avec l' -opérateur, ce qui a l'effet suivant:

    • Si une seule valeur est trouvée (c'est-à-dire que le caractère est apparu dans une seule entrée), cette valeur est retournée.
    • Si deux valeurs sont trouvées (c'est-à-dire que le caractère est apparu dans les deux entrées), soustrayez la deuxième valeur de la première.
  4. Additionnez la valeur absolue des valeurs de l'étape précédente.

pswg
la source
0

Scala , 134 81 octets

Merci @ ASCII uniquement pour leur travail.

(s,t)=>{var k::l::_=List(s,t)map(_.toLowerCase.toBuffer)
((k--l)++(l--k)).length}

Essayez-le en ligne!

V. Courtois
la source
81
ASCII uniquement le
ew, ça m'a manqué, j'ai des choses à apprendre en scalagolf
V. Courtois
Haha, j'ai probablement plus de choses à apprendre. Le premier étant Scala: P
ASCII uniquement le
ces tours étaient sympas cependant.
V. Courtois