끈 거리


28

도전

모두 소문자 문자열 [a-z]을 입력하면 문자 사이의 총 거리를 출력합니다.

Input: golf

Distance from g to o : 8
Distance from o to l : 3
Distance from l to f : 6

Output: 17

규칙

  • 금지 된 표준 허점
  • 이것은 -가장 짧은 대답은 바이트입니다.
  • 알파벳은 어느 방향에서나 이동할 수 있습니다. 항상 가장 짧은 경로를 사용해야합니다. ( x와 사이의 거리는 c5입니다).

1

테스트 사례

Input: aa
Output: 0

Input: stack
Output: 18

Input: zaza
Output: 3

Input: valleys
Output: 35

답변:


11

젤리 , 11 8 바이트

OIæ%13AS

@ Martin Ender 덕분에 3 바이트를 절약했습니다 .

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오.

설명

OIæ%13AS  Input: string Z
O         Ordinal. Convert each char in Z to its ASCII value
 I        Increments. Find the difference between each pair of values
  æ%13    Symmetric mod. Maps each to the interval (-13, 13]
      A   Absolute value of each
       S  Sum
          Return implicitly

6
나는 æ%며칠 전에 내장을 통해 읽는 동안이 문제를 해결하기 위해 많은 노력을 OIæ%13AS
Martin Ender

나는 이것이 9 바이트라고 생각한다 ( æ2 개).
Aleksei Zabrodskii

1
@elmigranto Jelly에는 각 문자를 1 바이트로 인코딩하는 코드 페이지가 있습니다. github.com/DennisMitchell/jelly/wiki/Code-page
ruds

10

하스켈, 57 56 바이트

q=map$(-)13.abs
sum.q.q.(zipWith(-)=<<tail).map fromEnum

사용 예 : sum.q.q.(zipWith(-)=<<tail).map fromEnum $ "valleys"-> 35.

작동 방식 :

q=map$(-)13.abs                -- helper function.
                               -- Non-pointfree: q l = map (\e -> 13 - abs e) l
                               -- foreach element e in list l: subtract the
                               -- absolute value of e from 13

               map fromEnum    -- convert to ascii values
      zipWith(-)=<<tail        -- build differences of neighbor elements
  q.q                          -- apply q twice on every element
sum                            -- sum it up

편집 : @Damien은 1 바이트를 저장했습니다. 감사!


회전 거리 트릭 ( q.q)에 감사드립니다
Leif Willerts

와우 좋은 하나! 1 바이트 이하 map의 정의를 추가 할 수 있습니다q
Damien

@Damien : 잘 발견되었습니다. 감사!
nimi

8

MATL , 14 , 10 바이트

dt_v26\X<s

온라인으로 사용해보십시오!

4 바이트를 절약 해 주신 @Suever 에게 감사드립니다 !

설명:

d           % Take the difference between consecutive characters
 t_         % Make a copy of this array, and take the negative of each element
   v        % Join these two arrays together into a matrix with height 2
    26\     % Mod 26 of each element
       X<   % Grab the minimum of each column
         s  % Sum these. Implicitly print

이전 버전:

d26\t13>26*-|s

6

파이썬 3, 69 68 바이트

lambda s:sum([13-abs(13-abs(ord(a)-ord(b)))for a,b in zip(s,s[1:])])

고장:

lambda s:
         sum(                                                      )
             [                             for a,b in zip(s,s[1:])]
              13-abs(13-abs(ord(a)-ord(b)))

1
전에 공백을 제거하면 1 바이트를 잃을 수 있습니다.for
Daniel

@Dopapp 아 그래, 고마워!
busukxuan

2
입력을 문자 목록으로 가져 와서 재귀를 사용하여 3 바이트를 절약 할 수 있습니다.f=lambda a,b,*s:13-abs(13-abs(ord(a)-ord(b)))+(s and f(b,*s)or 0)
Jonathan Allan

5

자바 126 120 117 바이트

int f(String s){byte[]z=s.getBytes();int r=0,i=0,e;for(;++i<z.length;r+=(e=(26+z[i]-z[i-1])%26)<14?e:26-e);return r;}

원래 버전의 버그를 지적하고 for-loop를 비우는 것을 제안한 @KevinCruijssen에게 감사합니다.

의 사용은 (26 + z[i] - z[i - 1]) % 26)다른 답변에 @Neil에 의해 코멘트에서 영감이다. (26 + ...)%26Math.abs(...)이유로 동일한 목적으로 사용됩니다 ...? e : 26 - e.

언 골프 :

int f(String s) {
    byte[]z = s.getBytes();
    int r = 0, i = 0, e;
    for (; ++i < z.length; r += (e = (26 + z[i] - z[i - 1]) % 26) < 14 ? e : 26 - e);
    return r;
}

사이트에 오신 것을 환영합니다! 이것이 무슨 언어 지? 문자 / 바이트는 몇 개입니까? 당신은해야 [edit] those details into the top of your post, with this markdown: #Language, n은 bytes`
DJMcMayhem

승인. 감사. 편집했습니다. 개선이 있습니까? :)
todeale

1
ungolfed 버전에서 -이전 e버전 이 누락되었습니다 .

2
PPCG에 오신 것을 환영합니다! 흠, 내가 "유형 불일치 : 바이트 INT에서 변환 할 수 없습니다"얻고에서 오류 e=z[i]-z[i-1];당신이 중 하나에 깁스를해야합니다 그래서 (byte)하거나 변경 eint. : 또한, 당신이 루프,이 같은 내부 모두를 배치하여 대한 루프 브래킷을 제거 할 수 있습니다 int f(String s){byte[]z=s.getBytes();int r=0,i=0,e;for(;++i<z.length;r+=(e=z[i]-z[i-1])>0?e<14?e:26-e:-e<14?-e:e+26);return r;}: (추신 :이 (가)에 대한 루프 불행하게도 같은 길이 반전 int f(String s){byte[]z=s.getBytes();int r=0,i=z.length-1,e;for(;i>0;r+=(e=z[i]-z[--i])>0?e<14?e:26-e:-e<14?-e:e+26);return r;}.
케빈 Cruijssen

1
감사합니다 @KevinCruijssen : D. 당신의 제안은 많은 도움이되었습니다.
todeale

3

자바 스크립트 (ES6), 84 82 79 바이트

Cyoce 덕분에 3 바이트 절약 :

f=([d,...s],p=parseInt,v=(26+p(s[0],36)-p(d,36))%26)=>s[0]?f(s)+(v>13?26-v:v):0

설명:

f=(
  [d,...s],                    //Destructured input, separates first char from the rest
  p=parseInt,                  //p used as parseInt
  v=(26+p(s[0],36)-p(d,36))%26 //v is the absolute value of the difference using base 36 to get number from char
  )
)=>
  s[0]?                        //If there is at least two char in the input
    f(s)                       //sum recursive call
    +                          //added to
    (v>13?26-v:v)              //the current shortest path
  :                            //else
    0                          //ends the recursion, returns 0

예 :
전화 : f('golf')
출력 :17


이전 솔루션 :

Neil 덕분에 82 바이트 :

f=([d,...s],v=(26+parseInt(s[0],36)-parseInt(d,36))%26)=>s[0]?f(s)+(v>13?26-v:v):0

84 바이트 :

f=([d,...s],v=Math.abs(parseInt(s[0],36)-parseInt(d,36)))=>s[0]?f(s)+(v>13?26-v:v):0

1
대신 Math.abs(...)당신은 사용할 수 있습니다 (26+...)%26; 어쨌든 13 이상의 값을 뒤집기 때문에 작동합니다. (이것이 MATL 답변의 작동 방식이라고 생각합니다.)
Neil

1
와 코드를 앞에 붙이는 몇 바이트를 저장 p=parseInt;하고 사용하는 p()대신parseInt()
Cyoce

3

루비, 73 바이트

->x{eval x.chars.each_cons(2).map{|a,b|13-(13-(a.ord-b.ord).abs).abs}*?+}

2

PHP, 93 바이트

for(;++$i<strlen($s=$argv[1]);)$r+=13<($a=abs(ord($s[$i-1])-ord($s[$i])))?$a=26-$a:$a;echo$r;

2

05AB1E , 12 바이트

SÇ¥YFÄ5Ø-}(O

설명

SÇ                   # convert to list of ascii values
  ¥                  # take delta's
   YF    }           # 2 times do
     Ä5Ø-            # for x in list: abs(x) - 13
          (O         # negate and sum

온라인으로 사용해보십시오!


바이트가 아닌 12 개의 기호입니다. UTF-8의 바이트 길이는 16입니다.
Aleksei Zabrodskii

@elmigranto : 그렇습니다. UTF-8의 경우에는 해당하지만 05AB1E는 12 바이트 인 CP-1252를 사용합니다.
Emigna

2

펄, 46 바이트

에 +3 포함 -p(코드 포함 ')

마지막 줄 바꿈없이 STDIN에 입력하십시오.

echo -n zaza | stringd.pl

stringd.pl:

#!/usr/bin/perl -p
s%.%$\+=13-abs 13-abs ord($&)-ord$'.$&%eg}{

2

라켓 119 바이트

(λ(s)(for/sum((i(sub1(string-length s))))(abs(-(char->integer
(string-ref s i))(char->integer(string-ref s(+ 1 i)))))))

테스트 :

(f "golf")

산출:

17

자세한 버전 :

(define(f s)
  (for/sum((i(sub1(string-length s))))
    (abs(-(char->integer(string-ref s i))
          (char->integer(string-ref s(+ 1 i)))))))

당신은 대체 할 수 (define(f s)(lambda(s)(익명 함수는 괜찮)이 짧은 바이트.
페더

1
라켓해야 잠깐, (λ(s)UTF8 인 경우 6 내가 생각 바이트, 이는 너무
fede의.

했어요 감사.
rnso

2

C #, 87 85 바이트

개선 된 솔루션 -Math.Abs ​​()를 add & modulo 트릭으로 대체하여 2 바이트를 절약했습니다.

s=>{int l=0,d,i=0;for(;i<s.Length-1;)l+=(d=(s[i]-s[++i]+26)%26)>13?26-d:d;return l;};

초기 해결책 :

s=>{int l=0,d,i=0;for(;i<s.Length-1;)l+=(d=Math.Abs(s[i]-s[++i]))>13?26-d:d;return l;};

온라인으로 사용해보십시오!

테스트 사례를 포함한 전체 소스 :

using System;

namespace StringDistance
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string,int>f= s=>{int l=0,d,i=0;for(;i<s.Length-1;)l+=(d=Math.Abs(s[i]-s[++i]))>13?26-d:d;return l;};

            Console.WriteLine(f("golf"));   //17
            Console.WriteLine(f("aa"));     //0
            Console.WriteLine(f("stack"));  //18
            Console.WriteLine(f("zaza"));   //3
            Console.WriteLine(f("valleys"));//35
        }
    }
}

2

실제로 21 바이트

부분적으로 cia_rana의 Ruby answer .

먼저지도를 목록으로 변환하지 않으면 ( 하단 요소 제외) 및 (첫 번째 요소 팝 )과 O함께 작동하지 않는 버그 (이 경우 map ord () 문자열에 대한)가있었습니다.dp# . 이 버그는 수정되었지만이 픽스가이 챌린지보다 최신이므로 수정 #했습니다.

편집 : 그리고 9 월 이후 바이트 수가 잘못되었습니다. 으악.

골프 제안을 환영합니다. 온라인으로 사용해보십시오!

O#;dX@pX♀-`A;úl-km`MΣ

언 골핑

         Implicit input string.
          The string should already be enclosed in quotation marks.
O#       Map ord() over the string and convert the map to a list. Call it ords.
;        Duplicate ords.
dX       Dequeue the last element and discard it.
@        Swap the with the duplicate ords.
pX       Pop the last element and discard it. Stack: ords[:-1], ords[1:]
♀-       Subtract each element of the second list from each element of the first list.
          This subtraction is equivalent to getting the first differences of ords.
`...`M   Map the following function over the first differences. Variable i.
  A;       abs(i) and duplicate.
  úl       Push the lowercase alphabet and get its length. A golfy way to push 26.
  -        26-i
  k        Pop all elements from stack and convert to list. Stack: [i, 26-i]
  m        min([i, 26-i])
Σ        Sum the result of the map.
         Implicit return.

1

자바 7,128 바이트

 int f(String s){char[]c=s.toCharArray();int t=0;for(int i=1,a;i<c.length;a=Math.abs(c[i]-c[i++-1]),t+=26-a<a?26-a:a);return t;}

언 골프

 int f(String s){
 char[]c=s.toCharArray();
 int t=0;
 for(int i=1,a;
     i<c.length;
   a=Math.abs(c[i]-c[i++-1]),t+=26-a<a?26-a:a);
return t;
 }

1

Pyth, 20 바이트

Lm-13.adbsyy-M.:CMQ2

STDIN에 인용 된 문자열을 입력하여 결과를 인쇄하는 프로그램.

온라인으로 사용해보십시오

작동 원리

Lm-13.adbsyy-M.:CMQ2  Program. Input: Q
L                     def y(b) ->
 m      b              Map over b with variable d:
  -13                   13-
     .ad                abs(d)
                CMQ   Map code-point over Q
              .:   2  All length 2 sublists of that
            -M        Map subtraction over that
          yy          y(y(that))
         s            Sum of that
                      Implicitly print

1

dc + od, 65 바이트

od -tuC|dc -e'?dsN0sT[lNrdsNr-d*vdD[26-]sS<Sd*vlT+sTd0<R]dsRxlTp'

설명:

에 있기 때문에 직류 당신이 문자열의 문자에 액세스 할 수 없습니다, 내가 사용 OD ASCII 값을 얻을 수 있습니다. 다음과 같이 스택 (LIFO 컨테이너)에서 역순으로 처리됩니다.

dsN0sT             # initialize N (neighbor) = top ASCII value, and T (total) = 0
[lNrdsNr-          # loop 'R': calculate difference between current value and N,
                   #updating N (on the first iteration the difference is 0)
   d*vdD[26-]sS<S  # get absolute value (d*v), push 13 (D) and call 'S' to subtract
                   #26 if the difference is greater than 13
   d*vlT+sT        # get absolute value again and add it to T
d0<R]dsR           # repeat loop for the rest of the ASCII values
xlTp               # the main: call 'R' and print T at the end

운영:

echo -n "golf" | ./string_distance.sh

산출:

17

1

C, 82 86 83 76 바이트

t,u;f(char*s){for(t=0;*++s;u=*s-s[-1],t+=(u=u<0?-u:u)>13?26-u:u);return t;}

입력 문자열이 1 자 이상이라고 가정합니다. 이것은 필요하지 않습니다#include<stdlib.h>

편집 : 아아, 시퀀스 포인트!

Ideone에서 사용해보십시오


ideone 컴파일러에서 문자열 "nwlrbb"및 모든 랜드 문자열 i를 시도 6 len 모든 0을 반환하지만 결과는 0이 아닌 것 같습니다 ....
RosLuP

네 이제 괜찮아 보입니다 ...
RosLuP

1

C, 70 바이트 76 바이트

k,i;f(char *s){for(i=0;*++s;i+=(k=abs(*s-s[-1]))>13?26-k:k);return i;}

1

스칼라, 68 바이트

def f(s:String)=(for(i<-0 to s.length-2)yield (s(i)-s(i+1)).abs).sum

비판은 환영합니다.


1

C #, 217 바이트

골프 :

IEnumerable<int>g(string k){Func<Char,int>x=(c)=>int.Parse(""+Convert.ToByte(c))-97;for(int i=0;i<k.Length-1;i++){var f=x(k[i]);var s=x(k[i+1]);var d=Math.Abs(f-s);yield return d>13?26-Math.Max(f,s)+Math.Min(f,s):d;}}

언 골프 드 :

IEnumerable<int> g(string k)
{
  Func<Char, int> x = (c) => int.Parse("" + Convert.ToByte(c)) - 97;
  for (int i = 0; i < k.Length - 1; i++)
  {
    var f = x(k[i]);
    var s = x(k[i + 1]);
    var d = Math.Abs(f - s);
    yield return d > 13 ? 26 - Math.Max(f, s) + Math.Min(f, s) : d;
  }
}

산출:

aa: 0
stack: 18
zaza: 3
valleys: 35

바이트로 변환 될 때 'a'는 97이므로 97이 각 빼기됩니다. 차이가 13보다 큰 경우 (즉, 알파벳의 절반) 26에서 각 문자 (바이트 값) 사이의 차이를 뺍니다. 마지막으로 "수율 반환"을 추가하면 몇 바이트가 절약되었습니다!


1
두 개의 쓸모없는 공백 : 's'앞 둘 다.
Yytsi

0

파이썬 3, 126 바이트

목록 에서 이해.

d=input()
print(sum([min(abs(x-y),x+26-y)for x,y in[map(lambda x:(ord(x)-97),sorted(d[i:i+2]))for i in range(len(d))][:-1]]))

좋은 대답입니다. 을 호출 abs(x-y)y-x이후로 대체 할 sortedx < y있습니다.
todeale

0

PHP, 79 바이트

for($w=$argv[1];$w[++$i];)$s+=13-abs(13-abs(ord($w[$i-1])-ord($w[$i])));echo$s;

0

자바, 109 바이트

int f(String s){int x=0,t,a=0;for(byte b:s.getBytes()){t=a>0?(a-b+26)%26:0;t=t>13?26-t:t;x+=t;a=b;}return x;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.