Clarence la lente dactylographe

35

introduction

Clarence est un commis à la saisie de données qui travaille chez un fournisseur de services Internet. Son travail consiste à saisir manuellement les adresses IP de tous les clients du fournisseur de services Internet dans la base de données. Il le fait en utilisant un clavier qui a la disposition suivante:

123
456
789
.0

La distance entre le centre des touches adjacentes horizontalement ou verticalement est exactement d’un centimètre. Par exemple, la distance entre les centres de 3et 9serait de deux centimètres. La distance entre les centres de 3et 5serait de √2cm. Le théorème de Pythagore suffit à calculer la distance entre deux clés quelconques.

Clarence, comme on peut s'y attendre de la part d'un fournisseur d'accès à Internet, utilise un système de frappe très lent et inefficace. Il utilise un seul doigt et cherche la clé, puis déplace son doigt sur la touche, puis appuie dessus, puis répète tous les chiffres du numéro. Vous connaissez peut-être ce style en tant que "système de recherche d'aigle" puisque le doigt cherche au-dessus du clavier la clé correcte avant de plonger pour appuyer sur la touche, comme un aigle plongeant pour tuer.

Par exemple, voici comment Clarence taperait le numéro 7851:

  1. Il commence son doigt 7et appuie sur la clé.
  2. Il déplace son doigt vers la droite de 1 cm 8et appuie sur la touche.
  3. Il bouge son doigt de 1 cm vers le haut 5et appuie sur la touche.
  4. Il déplace son doigt en diagonale vers le haut et à gauche de √2 cm 1et appuie sur la touche.

Par conséquent , la distance totale parcourue par Clarence déplacé son doigt taper 7851est -ce 1 + 1 + √2qui représente environ 3.41cm.

Votre tâche consiste à écrire un programme calculant la distance à laquelle Clarence doit déplacer son doigt pour saisir des adresses IP arbitraires.

Description de l'entrée

L'entrée est une chaîne qui sera sous la forme

().().().()

où chacun ()est un entier compris dans l'intervalle 0- 999. Cela représente l'adresse IP que Clarence doit taper. Un exemple d'entrée pourrait être:

219.45.143.143

J'aimerais également souligner que des entrées telles que 0.42.42.42ou 999.999.999.999sont toujours valables, malgré le fait qu'elles soient des adresses IP non valides. Vous n'avez donc pas besoin d'inclure de code de vérification d'adresse IP dans votre programme.

Description de la sortie

Indiquez la distance à laquelle Clarence doit déplacer son doigt pour saisir l'adresse IP spécifiée. Arrondissez les réponses à deux décimales si nécessaire et utilisez l’ cmunité dans votre sortie. La sortie pour l'exemple d'entrée est 27.38cm(1 + √8 + √5 + 2 + 1 + √5 + 3 + 1 + √5 + √13 + 3 + 1 + √5).

Absinthe
la source
29
Les FAI ont des claviers étranges ...
Dennis
1
@RetoKoradi Je m'attends à un programme, oui. stdin, les arguments de ligne de commande ou les fonctions d'entrée utilisateur sont acceptables.
absinthe
2
@dacapoaria - La "recherche d'aigle" est également connue sous le nom de "chasser et picorer" ou "rechercher et détruire" pour les dactylographes les plus exigeants.
12
@ArtofCode Clarence travaille chez un FAI, qui lui envoie parfois les données non valides à saisir dans la base de données. Clarence tape les données de toute façon. C'est la raison canonique de toute façon. La raison réelle est parce que j'ai négligé cela lors de la rédaction de la spécification.
absinthe
3
En considérant uniquement la plage valide (0-255) Adresses IP, quel devrait être l'arrangement optimal du clavier pour taper toutes les adresses dans le chemin le plus court?
Israël Morales

Réponses:

16

CJam, 46 44 43 38 37 34 octets

rA,sd`f#3fmd2/2ew::.-::mh:+2mO"cm"

Merci à @ user23013 de nous avoir suggéré mh, ce qui a permis d’économiser 5 octets.

Essayez-le en ligne dans l' interprète CJam .

Comment ça marche

r     e# Read a token from STDIN.
A,    e# Push [0 1 2 3 4 5 6 7 8 9].
s     e# Stringify: [0 1 2 3 4 5 6 7 8 9] -> "0123456789"
d     e# Cast to Double: "0123456789" -> 123456789.0
`     e# Inspect: 123456789.0 -> "123456789.0"
f#    e# Push the index of each character from the input in "123456789.0".
3fmd  e# Push the quotient and residue of each index divided by 3.
2/    e# Split the resulting array into pairs.
2ew   e# Convert the array of pairs in the array of all overlapping pairs of pair.
::.-  e# Reduce each pair using vectorized difference: [[a b][c d]] -> [a-b c-d]
::mh  e# Reduce each reduced pair to its 2-norm distance: [a b] -> sqrt(aa + bb)
:+    e# Sum all distances.
2mO   e# Round to two decimal places.
"cm"  e# Push "cm".
Dennis
la source
2
{3fmd~@-@@-mh}%.
jimmy23013
@ user23013: Merci. Je n'avais aucune idée mhmême existé.
Dennis
16

Pyth, 38 35 34 octets

+.Rs.aM-M.:m.jF.Dx`ciUTT1b3z2 2"cm

Manifestation.

Indexation dans la chaîne d'une idée float grâce à @Dennis.

Explication, sur l'entrée bidon 15.0:

  • Tout d'abord, nous prenons l'entrée. Il est implicitement stocké dans z. '15 .0 '
  • Nous identifions cette liste comme suit: m.jF.Dx`ciUTT1k3z.

    • UT: Nous générons la liste [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
    • iUTT: Ensuite, nous traitons cette liste comme un numéro de base 10 nous donnant 123456789.
    • ciUTT1: Ensuite, nous convertissons ce nombre en un nombre à virgule flottante en le divisant par 1, ce qui donne 123456789.0.
    • `: Convertir en chaîne. '123456789.0'
    • x k: Prend l'index du caractère saisi dans cette chaîne. [0, 4, 9, 10].
    • .D 3: .Dest la fonction divmod, qui sort sa première entrée divisée et modulo par la deuxième entrée. La deuxième entrée est 3, ici. Cela donne l'emplacement physique du personnage sur le pavé numérique. [(0, 0), (1, 1), (3, 0), (3, 1)].
    • .jF: .jest le constructeur du nombre complexe. Fl'applique au tuple. [0j, (1+1j), (3+0j), (3+1j)].
  • .: 2: Maintenant, prenons les 2 sous-chaînes d’entrée de cette liste pour pouvoir trouver les distances par paires. [[0j, (1+1j)], [(1+1j), (3+0j)], [(3+0j), (3+1j)]].
  • -M: Prend la différence des deux nombres complexes. [(-1-1j), (-2+1j), -1j].
  • .aM: Prend la valeur absolue du résultat. C'est la distance entre les emplacements des claviers.[1.4142135623730951, 2.23606797749979, 1.0]
  • s: Somme les distances. 4.650281539872885.
  • .R 2: Arrondir à 2 décimales. 4.65.
  • + "cm: Ajouter 'cm'à la fin et imprimer. 4.65cm.
isaacg
la source
7

PHP - 108 octets

<?for(;$v=strpos(-.987654321,fgetc(STDIN));$l=$v)$l&&$t+=hypot($l/3%4-$v/3%4,$l%3-$v%3);printf('%.2fcm',$t);

L'entrée est prise de stdin. Le -.987654321message envoyé à la strposfonction est évalué '-0.987654321'dans un contexte de chaîne.


Exemple d'utilisation:

$ echo 219.45.143.143 | php isp.php
27.38cm
primo
la source
5

C, 192 177 159 octets

Version mise à jour, programme maintenant complet en utilisant l’argument de la ligne de commande. Dans le même temps, amélioré pour être toujours plus court que la version précédente:

#define G c=*a[1]++,c=c>48?c-49:c/2-14,u=c%3,v=c/3
float r;c,u,v,p,q;main(int n,char**a){for(G;*a[1];)p=u,q=v,G,p-=u,q-=v,r+=sqrt(p*p+q*q);printf("%.2fcm",r);}

Ungolfed:

#include <stdio.h>
#include <math.h>

float r;
int c, u, v, p, q;

int main(int n, char** a) {
    c = *a[1]++;
    c = c > 48 ? c - 49 : c / 2 - 14;
    u = c % 3;
    v = c / 3;
    for ( ; *a[1]; ) {
        p = u;
        q = v;
        c = *a[1]++;
        c = c > 48 ? c - 49 : c / 2 - 14;
        u = c % 3;
        v = c / 3;
        p -= u;
        q -= v;
        r += sqrt(p * p + q * q);
    }

    printf("%.2fcm",r);

    return 0;
}

La version golfée utilise un préprocesseur #definepour raccourcir une partie du code répété dans la version complète.

Reto Koradi
la source
2
1. Votre version golfée manque un point-virgule à la fin. 2. Votre version jouée au golf produit des résultats incorrects, puisque vous incrémentez savant de vérifier que ce *sn'est pas nul. 3. L'OP dit programme à son poste. Je ne suis pas sûr si une fonction est acceptée. 4. Avec GCC, vous n'avez pas besoin d'inclure. 5. sqrtest plus court que sqrtf. 6. pow(u-p,2)est plus court que (u-p)*(u-p). 7. Je ne suis pas sûr, mais je pense que le stockage dans les deux coordonnées une seule chaîne et la mise u=x[c]/3et v=x[c]%3devrait être plus courte.
Dennis
Correction du problème de correction. Il s'avère que j'ai continué à compiler une version antérieure tout en effectuant des réglages précis. Désolé pour ça. 1, 2. Fixe. En fait, j'ai été surpris de pouvoir les laisser partir. Le test interrompu expliquerait cela… 3. D'après ce que j'ai vu sur wiki / meta, il semblerait que prendre l'entrée en tant qu'arguments de fonction est une option autorisée si l'entrée n'est pas spécifiée explicitement. Je vais le changer si mon interprétation est incorrecte. 4. J'ai toujours pensé que seules les fonctions qui revenaient intpouvaient être utilisées non déclarées. Mais en fait, Clang l'accepte aussi avec un avertissement, alors je m'en suis débarrassé.
Reto Koradi
Le wiki indique que les fonctions sont autorisées par défaut, oui, mais l'OP a écrit que votre tâche est d'écrire un programme ... Vous n'avez pas besoin des crochets que vous avez introduits si vous écrivez la boucle p=u,q=v,G,r+=....
Dennis
J'ai demandé à l'OP de clarifier les exigences d'entrée. Sur le code, je l'ai restauré à une version légèrement plus ancienne avant de l'optimiser de manière incorrecte. Je tenterai encore une fois de le régler demain, mais je ne voulais pas laisser une version brisée debout trop longtemps. Merci pour les pointeurs.
Reto Koradi
@Dennis Ok, la version mise à jour devrait être meilleure à tous égards. Maintenant, un programme complet et encore plus court grâce à certaines optimisations. Merci encore de m'avoir informé des problèmes liés à la version initiale.
Reto Koradi
3

JavaScript ( ES6 ), 132

I / O via popup. Exécutez l'extrait de code pour tester (Firefox uniquement)

[for(a of prompt(d=''))[p,q,d]=[x=(a=a<'0'?9:-a?a-1:10)%3,y=a/3|0,d!==''?d+Math.sqrt((p-=x)*p+(q-=y)*q):0]],alert(d.toFixed(2)+'cm')

edc65
la source
3

Python 3, 108 octets

L=[x//3*1j+x%3for x in map("123456789.0".find,input())]
print("%.2fcm"%sum(abs(a-b)for a,b in zip(L,L[1:])))

Certes, pas très bien joué au golf, mais au moins, il est lié à PHP.

Sp3000
la source
2

Ruby 135 139

s=0
gets.chars.each_cons(2).map{|a|i,j=a.map{|e|'123456789.0'.index e}
i&&j&&s+=((i%3-j%3)**2+(i/3-j/3)**2)**0.5}
print s.round(2),'cm'

Testez-le en ligne: http://ideone.com/2CIQa5

Cristian Lupascu
la source
2

Python 199 171 166

Il existe un code Python plus court (108) pour cela par SP3000:

https://codegolf.stackexchange.com/a/50854/41163

import sys
p=r=0
for i in sys.argv[1]:
 c=3,0
 if i!=".":c=divmod(int(i)-1,3)
 if i<1:c=3,1
 if p:r+=((p[1]-c[1])**2+(p[0]-c[0])**2)**0.5
 p=c
print"%.2fcm"%r

Exemple d'utilisation:

$ python isp.py 219.45.143.143
27.38cm

Courez en ligne: http://codepad.org/h9CWCBNO

Code commenté

import sys

# p - last position as (y,x) tuple - initialized with 0, because "if 0" -> equals to "False"
p = 0
# r - result of adding all distances - ini with 0, because not moved any distances on start
r = 0

# Loop over chars
for char in sys.argv[1]:
   # c - current position of typist as (y,x) tuple

   # Always set c to position of "." key 
   c = 3,0 # lazy for c=(3,0)

   # Check if char is not the "." key
   if char !=".":

      # Get position of char on keypad
      c=divmod(int(char)-1,3)

      if char<1:
         c=3,1  

   # If this is the first char, 
   # then STORE_OPERATION has not been executed, 
   # so p is still p=0 from original initialization 
   # calling "if 0" evaluates to False,
   # so we jump this code block, for the first char
   if p:                           
      # calculate delta of x, y from current and last position, 
      # then add both deltas squared (**2),
      # then get square root of it (**0.5 = **1/2)
      # add to r (+=)
      r+=( (p[1]-c[1])**2 + (p[0]-c[0])**2 )**0.5

   # STORE_OPERATION - Store current position as last position
   p = c

# .2f returns r with 2 trailing digits
print"%.2fcm"%r
Ajout de couleur
la source
1
Vous pouvez économiser des octets en définissant des ifclauses sur une seule ligne, par exempleif i<1:c=3,1
Zgarb
1
Vous pouvez ajouter une coloration syntaxique en mettant ce commentaire en haut de votre message:<!-- language: lang-python -->
Martin Ender