Clarence Wolny Maszynistka


35

Wprowadzenie

Clarence jest pracownikiem ds. Wprowadzania danych, który pracuje u dostawcy usług internetowych. Jego zadaniem jest ręczne wprowadzanie adresów IP wszystkich klientów usługodawcy internetowego do bazy danych. Robi to za pomocą klawiatury, która ma następujący układ:

123
456
789
.0

Odległość między środkiem sąsiednich klawiszy poziomo lub pionowo wynosi dokładnie jeden centymetr. Na przykład odległość między środkami 3i 9wynosiłaby dwa centymetry. Odległość między środkami 3i 5wynosiłaby √2 cm. Twierdzenie Pitagorasa jest wystarczające do obliczenia odległości między dowolnymi dwoma kluczami.

Clarence, jak można oczekiwać od osoby pracującej w ISP, używa bardzo wolnego i nieefektywnego systemu pisania. Używa jednego palca i szuka klucza, a następnie przesuwa palec do klawisza, a następnie naciska go i powtarza dla wszystkich cyfr w numerze. Być może znasz ten styl jako „system wyszukiwania orła”, ponieważ palec szuka nad klawiaturą odpowiedniego klawisza, zanim pogrąży się w naciśnięciu klawisza, jak orzeł pogrążający się w celu zabicia.

Na przykład oto, jak Clarence wpisałby liczbę 7851:

  1. Zaczyna palcem 7i wciska klucz.
  2. Przesuwa palec w prawo o 1 cm 8i naciska klawisz.
  3. Przesuwa palec w górę o 1 cm 5i naciska klucz.
  4. Przesuwa palec po przekątnej w górę, pozostawia około 2 cm 1i naciska klawisz.

Dlatego też całkowita odległość, że Clarence przeniósł swój palec, aby wpisać 7851Is 1 + 1 + √2co stanowi około 3.41cm.

Twoim zadaniem jest napisanie programu, który oblicza odległość, którą Clarence musi przesunąć palcem, aby wpisać dowolne adresy IP.

Opis wejścia

Dane wejściowe to ciąg znaków, który będzie w formie

().().().()

gdzie każda ()jest liczbą całkowitą w zakresie 0- 999. To reprezentuje adres IP, który musi wpisać Clarence. Przykładem może być:

219.45.143.143

Chciałbym również zauważyć, że dane wejściowe takie jak 0.42.42.42lub 999.999.999.999są nadal prawidłowe, mimo że są one nieprawidłowymi adresami IP. Dlatego nie musisz dołączać żadnego kodu weryfikacyjnego adresu IP do swojego programu.

Opis wyjścia

Podaj odległość, którą Clarence musi przesunąć palcem, aby wpisać określony adres IP. W razie potrzeby zaokrąglaj odpowiedzi do dwóch miejsc po przecinku i używaj cmjednostki w wynikach. Dane wyjściowe dla przykładowego wejścia to 27.38cm(1 + √8 + √5 + 2 + 1 + √5 + 3 + 1 + √5 + √13 + 3 + 1 + √5).


29
Człowieku, dostawcy usług internetowych mają dziwne klawiatury ...
Dennis

1
@RetoKoradi Oczekuję programu, tak. dopuszczalne są standardowe wejście, argumenty wiersza poleceń lub funkcje wprowadzania danych przez użytkownika.
absynt

2
@dacapoaria - „wyszukiwanie orła” jest również znane jako „polowanie i dziobanie” lub „poszukiwanie i niszczenie” dla cięższych maszynistek.

12
@ArtofCode Clarence pracuje u dostawcy usług internetowych, a czasami dostawca usług internetowych wysyła mu nieprawidłowe dane do wpisania do bazy danych. Clarence i tak wpisuje dane. To zresztą kanoniczny powód. Rzeczywistym powodem jest to, że przeoczyłem to podczas pisania specyfikacji.
absynt

3
Biorąc pod uwagę tylko prawidłowy zakres (0–255) adresów IP, jaki powinien być optymalny układ klawiatury do wpisywania wszystkich adresów w najkrótszej ścieżce?
Israel Morales

Odpowiedzi:


16

CJam, 46 44 43 38 37 34 bajtów

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

Dzięki @ user23013 za sugestie mh, które pozwoliły zaoszczędzić 5 bajtów.

Wypróbuj online w interpretatorze CJam .

Jak to działa

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".

2
{3fmd~@-@@-mh}%.
jimmy23013

@ user23013: Dzięki. mhNawet nie miałem pojęcia, że istnieje.
Dennis

16

Pyth, 38 35 34 bajtów

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

Demonstracja.

Indeksowanie w ciąg idei typu float dzięki @Dennis.

Objaśnienie na fałszywym wejściu 15.0:

  • Najpierw bierzemy wkład. Jest niejawnie przechowywany w z. „15,0”
  • Mamy map do tej listy w następujący sposób: m.jF.Dx`ciUTT1k3z.

    • UT: Generujemy listę [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
    • iUTT: Następnie traktujemy tę listę jako podstawową liczbę 10, która nam daje 123456789.
    • ciUTT1: Następnie konwertujemy tę liczbę na liczbę zmiennoprzecinkową, dzieląc ją przez 1, dając 123456789.0.
    • `: Konwertuj na ciąg. '123456789.0'
    • x k: Weź indeks znaku wejściowego w tym ciągu. [0, 4, 9, 10].
    • .D 3: .Djest funkcją divmod, której pierwsze wejście jest dzielone i modulowane przez drugie wejście. Drugie wejście to 3 tutaj. Daje to fizyczną lokalizację postaci na klawiaturze numerycznej. [(0, 0), (1, 1), (3, 0), (3, 1)].
    • .jF: .jjest konstruktorem liczb zespolonych. Fstosuje to do krotki. [0j, (1+1j), (3+0j), (3+1j)].
  • .: 2: Teraz bierzemy 2 podciągi wejściowe z tej listy, abyśmy mogli znaleźć odległości parami. [[0j, (1+1j)], [(1+1j), (3+0j)], [(3+0j), (3+1j)]].
  • -M: Bierze różnicę między dwiema liczbami zespolonymi. [(-1-1j), (-2+1j), -1j].
  • .aM: Przyjmuje wartość bezwzględną wyniku. Jest to odległość między lokalizacjami klawiatury.[1.4142135623730951, 2.23606797749979, 1.0]
  • s: Zsumuj odległości. 4.650281539872885.
  • .R 2: Zaokrąglić do 2 miejsc po przecinku. 4.65.
  • + "cm: Dodaj 'cm'na końcu i wydrukuj. 4.65cm.

7

PHP - 108 bajtów

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

Dane wejściowe są pobierane ze standardowego wejścia. -.987654321Wysyłane do strposfunkcji ocenia się '-0.987654321'w kontekście strun.


Przykładowe użycie:

$ echo 219.45.143.143 | php isp.php
27.38cm

5

C, 192 177 159 bajtów

Zaktualizowana wersja, teraz zakończ program, używając argumentu wiersza poleceń. Jednocześnie poprawiono, by nadal był krótszy niż poprzednia wersja:

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

Nie golfowany:

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

Wersja do gry w golfa wykorzystuje preprocesor, #defineaby skrócić część powtarzanego kodu w pełnej wersji.


2
1. W twojej wersji golfowej brakuje na końcu średnika. 2. Twoja wersja w golfa daje nieprawidłowe wyniki, ponieważ zwiększasz sprzed sprawdzeniem, *sczy nie jest zerem. 3. OP powiedział program na swoim stanowisku. Nie jestem pewien, czy funkcja jest akceptowana. 4. Z GCC nie potrzebujesz dołączenia. 5. sqrtjest krótszy niż sqrtf. 6. pow(u-p,2)jest krótszy niż (u-p)*(u-p). 7. Nie jestem pewien, ale myślę, że przechowywanie zarówno współrzędne w jednym ciągu i ustawienie u=x[c]/3i v=x[c]%3powinien być krótszy.
Dennis

Naprawiono problem z poprawnością. Okazuje się, że kompilowałem wcześniejszą wersję, jednocześnie dostrajając. Przepraszam za to. 1, 2. Naprawiono. Byłem właściwie zaskoczony, że mogłem je zostawić. Zepsute testowanie wyjaśniłoby to ... 3. W oparciu o to, co widziałem na wiki / meta, brzmiało to tak, jakby przyjmowanie danych wejściowych jako argumentów funkcji było dozwoloną opcją, jeśli dane wejściowe nie zostały wyraźnie określone. Zmienię to, jeśli moja interpretacja będzie niepoprawna. 4. Zawsze myślałem, że tylko funkcje, które zwracają, intmogą być używane niezadeklarowane. Ale rzeczywiście klang również przyjmuje to z ostrzeżeniem, więc się go pozbyłem.
Reto Koradi

Wiki stwierdza, że ​​funkcje są domyślnie dozwolone, tak, ale OP napisał, że Twoim zadaniem jest napisanie programu ... Nie potrzebujesz nawiasów, które wprowadziłeś, jeśli piszesz pętlę jako p=u,q=v,G,r+=....
Dennis

Poprosiłem PO o wyjaśnienie wymagań dotyczących nakładów. W kodzie przywróciłem go do nieco starszej wersji, zanim zoptymalizowałem go do niepoprawności. Jutro spróbuję go nastroić, ale nie chciałem pozostawić uszkodzonej wersji na zbyt długo. Dzięki za wskazówki.
Reto Koradi

@Dennis Ok, zaktualizowana wersja powinna być lepsza pod każdym względem. Teraz kompletny program i jeszcze krótszy dzięki niektórym optymalizacjom. Jeszcze raz dziękuję za poinformowanie mnie o problemach z pierwszą wersją.
Reto Koradi

3

JavaScript ( ES6 ), 132

I / O przez wyskakujące okienko. Uruchom fragment kodu, aby przetestować (tylko Firefox)

[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')


3

Python 3, 108 bajtów

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:])))

Wprawdzie niezbyt dobrze gra w golfa, ale przynajmniej wiąże się z PHP.



2

Python 199171 166

Jest to krótszy kod Python (108) dla tego 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

Przykładowe użycie:

$ python isp.py 219.45.143.143
27.38cm

Uruchom online: http://codepad.org/h9CWCBNO

Skomentowany kod

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

1
Możesz zapisać niektóre bajty, definiując ifklauzule w jednym wierszu, na przykładif i<1:c=3,1
Zgarb

1
Możesz dodać wyróżnianie składni, umieszczając ten komentarz na początku swojego postu:<!-- language: lang-python -->
Martin Ender
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.