Jarak Tali


28

Tantangan

Diberikan input dari string semua-huruf kecil [a-z], output jarak total antara huruf.

Contoh

Input: golf

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

Output: 17

Aturan

  • Celah standar dilarang
  • Ini adalah - jawaban terpendek dalam byte yang menang.
  • Alfabet dapat dilintasi dari kedua arah. Anda harus selalu menggunakan jalur terpendek. (Yaitu jarak antara xdan c5).

1

Uji kasus

Input: aa
Output: 0

Input: stack
Output: 18

Input: zaza
Output: 3

Input: valleys
Output: 35

Jawaban:


11

Jelly , 11 8 byte

OIæ%13AS

Disimpan 3 byte berkat @ Martin Ender .

Cobalah online! atau Verifikasi semua kasus uji.

Penjelasan

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
Saya menemukan æ%saat membaca built-in hari yang lain, dan itu cukup banyak dibuat untuk masalah (jenis) ini:OIæ%13AS
Martin Ender

Saya pikir ini adalah 9 byte ( ædua).
Aleksei Zabrodskii

1
@elmigranto Jelly memiliki codepage yang menyandikan setiap karakternya dalam satu byte: github.com/DennisMitchell/jelly/wiki/Code-page
ruds

10

Haskell, 57 56 byte

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

Contoh penggunaan: sum.q.q.(zipWith(-)=<<tail).map fromEnum $ "valleys"-> 35.

Bagaimana itu bekerja:

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

Sunting: @Damien menyimpan satu byte. Terima kasih!


terima kasih untuk trik jarak rotasi ( q.q)
Leif Willerts

Wow, bagus! Anda dapat menambahkan mapdefinisi kurang dari qsatu byte
Damien

@ Damen: terlihat dengan baik. Terima kasih!
nimi

8

MATL , 14 , 10 byte

dt_v26\X<s

Cobalah online!

Terima kasih @Suever karena telah menghemat 4 byte!

Penjelasan:

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

Versi sebelumnya:

d26\t13>26*-|s

6

Python 3, 69 68 byte

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

Kerusakan:

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

1
Anda dapat kehilangan satu byte dengan menghapus spasi sebelumnyafor
Daniel

@Dappapp Oh ya, terima kasih!
busukxuan

2
Anda dapat mengambil input sebagai daftar karakter dan menggunakan rekursi untuk menghemat 3 byte:f=lambda a,b,*s:13-abs(13-abs(ord(a)-ord(b)))+(s and f(b,*s)or 0)
Jonathan Allan

5

Java, 126 120 117 byte

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

Terima kasih kepada @KevinCruijssen karena menunjukkan bug dalam versi asli dan menyarankan untuk membuat for-loop kosong.

Penggunaan (26 + z[i] - z[i - 1]) % 26)terinspirasi dari komentar oleh @Neil pada jawaban lain. (26 + ...)%26melayani tujuan yang sama Math.abs(...)karena ...? e : 26 - e.

Tidak Terkumpul :

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

Selamat datang di situs ini! Bahasa apa ini? Berapa banyak karakter / byte? Anda harus [edit] those details into the top of your post, with this markdown: #Language, n bytes`
DJMcMayhem

Baik. Terima kasih. Saya sudah mengeditnya. Adakah perbaikan? :)
todeale

1
Anda kehilangan tanda -sebelum edalam versi yang tidak dikoleksi.
Neil

2
Selamat datang di PPCG! Hmm, saya mendapatkan "Ketidakcocokan tipe: tidak dapat mengkonversi dari int ke byte" di e=z[i]-z[i-1];Jadi Anda juga perlu pemain untuk (byte)atau mengubah eke int. Juga, Anda dapat menghapus untuk loop kurung dengan menempatkan segala sesuatu di dalam untuk loop, seperti ini: 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;}(PS: The terbalik untuk loop sayangnya sama panjang: 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;}.
Kevin Cruijssen

1
Terima kasih banyak @KevinCruijssen: D. Saran Anda telah banyak membantu.
todeale

3

JavaScript (ES6), 84 82 79 byte

Disimpan 3 byte berkat Cyoce:

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

Penjelasan:

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

Contoh:
Panggilan: f('golf')
Keluaran:17


Solusi sebelumnya:

82 byte berkat Neil:

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

84 byte:

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

1
Alih-alih Math.abs(...)Anda bisa menggunakan (26+...)%26; ini berhasil karena Anda membalik nilai di atas 13. (Saya pikir ini adalah bagaimana jawaban MATL bekerja.)
Neil

1
Simpan beberapa byte dengan mengawali kode dengan p=parseInt;dan kemudian menggunakan p()alih-alihparseInt()
Cyoce

3

Ruby, 73 byte

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

2

PHP, 93 Bytes

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 byte

SÇ¥YFÄ5Ø-}(O

Penjelasan

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

Cobalah online!


Ini 12 simbol, bukan byte. Panjang Byte adalah 16 untuk UTF-8.
Aleksei Zabrodskii

@elmigranto: Memang. Dalam UTF-8 itu akan terjadi, tetapi 05AB1E menggunakan CP-1252 di mana ini adalah 12 byte.
Emigna

2

Perl, 46 byte

Termasuk +3 untuk -p(kode berisi ')

Berikan masukan pada STDIN tanpa baris akhir final:

echo -n zaza | stringd.pl

stringd.pl:

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

2

Racket 119 byte

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

Pengujian:

(f "golf")

Keluaran:

17

Versi detail:

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

Anda dapat mengganti (define(f s)dengan (lambda(s), 2 byte lebih pendek (fungsi anonim baik-baik saja).
fede s.

1
Tunggu, Racket juga harus mengambil (λ(s), yang jika di utf8 adalah 6 byte saya pikir
fede s.

Selesai itu. Terima kasih.
rnso

2

C #, 87 85 byte

Solusi yang ditingkatkan - menggantikan Math.Abs ​​() dengan trik add & modulo untuk menghemat 2 byte:

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

Solusi awal :

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

Cobalah online!

Sumber lengkap, termasuk uji kasus:

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

Sebenarnya, 21 byte

Didasarkan sebagian pada jawaban Ruby cia_rana .

Ada bug dengan O(dalam hal ini, peta ord () di atas string) di mana ia tidak akan bekerja dengan d(elemen bawah dequeue) dan p(elemen pertama pop) tanpa terlebih dahulu mengubah peta ke daftar #. Bug ini telah diperbaiki, tetapi karena perbaikannya lebih baru daripada tantangan ini, maka saya tetap menyimpannya #.

Sunting: Dan jumlah byte sudah salah sejak September. Aduh.

Saran bermain golf diterima. Cobalah online!

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

Tidak melakukanolf

         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

Java 7.128 byte

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

Tidak disatukan

 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 byte

Lm-13.adbsyy-M.:CMQ2

Program yang mengambil input dari string yang dikutip pada STDIN dan mencetak hasilnya.

Cobalah online

Bagaimana itu bekerja

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 byte

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

Penjelasan:

Karena di dc Anda tidak dapat mengakses karakter string, saya menggunakan od untuk mendapatkan nilai ASCII. Ini akan diproses dalam urutan terbalik dari tumpukan (wadah LIFO) seperti:

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

Menjalankan:

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

Keluaran:

17

1

C, 82 86 83 76 byte

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

Mengasumsikan string input setidaknya satu karakter. Ini tidak perlu#include<stdlib.h>

Sunting: Argh, titik urutan!

Cobalah di Ideone


dalam ideone compiler string "nwlrbb" dan semua string rand saya coba 6 len kembalikan semua 0 tetapi tampaknya bukan 0 hasilnya ....
RosLuP

ya sekarang sepertinya ok ...
RosLuP

1

C, 70 byte 76 byte

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

1

Scala, 68 byte

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

Kritik dipersilahkan.


1

C #, 217 byte

Golf:

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

Tidak Terkumpul:

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

Keluaran:

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

'a' adalah 97 ketika dikonversi ke byte, jadi 97 dikurangkan dari masing-masing. Jika perbedaannya lebih besar dari 13 (yaitu, setengah dari alfabet), maka kurangi perbedaan antara masing-masing karakter (nilai byte) dari 26. Tambahan menit terakhir "hasil pengembalian" menyelamatkan saya beberapa byte!


1
Dua ruang putih yang tidak berguna: keduanya sebelum 's'.
Yytsi

0

Python 3, 126 byte

Dengan daftar di pemahaman.

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

Jawaban bagus. Anda dapat mengganti abs(x-y)dengan y-xsejak panggilan sorteddibuat x < y.
todeale

0

PHP, 79 byte

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

0

Java, 109 byte

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;
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.