Penambahan-Pengurangan Angka Dalam String

14

Ambil string sebagai input, dan lakukan penambahan / pengurangan semua digit dalam string dan hasilkan jumlah operasi tersebut sebagai hasilnya.

Aturan

  • Digit dalam string dibaca dari kiri ke kanan
  • Jika digit (n) ganjil, lakukan penambahan dengan digit berikutnya (n + n1)
  • Jika digit (n) genap, lakukan pengurangan dengan digit berikutnya (n - n1)
  • Jika Anda telah mencapai digit terakhir dalam string, lakukan operasi dengan digit pertama dalam string
  • Output akan menjadi jumlah dari semua nilai yang dihasilkan
  • Jika hanya ada satu digit dalam string, lakukan operasi dengan sendirinya (n + n atau nn)
  • Jika tidak ada digit dalam string, output adalah 0

Contoh

Input: r5e6o9mm!/3708dvc    
Process: (5+6) + (6-9) + (9+3) + (3+7) + (7+0) + (0-8) + (8-5)
Output: 32

Catatan

  • Fungsi atau program lengkap diterima
  • Panjang input maksimum akan tergantung pada batas bahasa Anda untuk input string
  • Tidak ada batasan pada input karakter, tetapi hanya digit setengah lebar yang dihitung untuk output
  • Bytes paling sedikit menang
Noir Antares
sumber
4
Beberapa contoh lagi juga akan bagus
dylnan
2
Saya akan merekomendasikan untuk menambahkan test case yang diakhiri dengan angka ganjil.
Arnauld
3
Disarankan testcase: "", "0","1"
TSH
1
Bisakah kita mengambil input sebagai array karakter daripada string? (Julia membuat perbedaan di antara keduanya.)
sundar - Reinstate Monica
4
@sundar Konsensus saat ini adalah string didefinisikan sebagai urutan karakter. Pemahaman saya adalah bahwa array karakter karenanya diizinkan secara default bahkan jika bahasa Anda memiliki tipe string asli
Arnauld

Jawaban:

6

Jelly , 17 15 12 byte

fØDV€ḂT‘ịƲSḤ

Cobalah online!

Coba uji kasus.

Program ini hanya menyimpan digit yang mengikuti digit ganjil kemudian menghitung dua kali jumlah.

fØDV€ḂT‘ịƲSḤ   
f                   Remove anything that isn't...
 ØD                 a digit.
   V€               Cast each digit to an integer
         Ʋ          Monad:
     Ḃ              Parity of each digit.
      T             Indices of truthy elements (odd digits).
       ‘            Increment.
        ị           Index into list of digits.
                    Wraps to beginning and if there are no digits this returns 0.
          S         Sum.
           Ḥ        Double.
dylnan
sumber
3

K (oK) , 47 43 40 31 byte

Larutan:

{+/(1_x,*x)*2*2!x^:(x-:48)^!10}

Cobalah online!

Penjelasan:

Hapus semua dari string yang bukan angka (sementara juga mengkonversi), modulo 2, kalikan dengan 2, kalikan dengan x yang diputar oleh 1, dan jumlahkan.

{+/(1_x,*x)*2*2!x^:(x-:48)^!10} / solution
{                             } / lambda taking implicit x
                           !10  / range 0..10
                          ^     / except
                   (     )      / do this together
                    x-:48       / subtract 48 from x (type fudging char ascii value -> ints), save back into x
                x^:             / x except right, and save back to x
              2!                / modulo 2
            2*                  / multiply by 2
           *                    / multiply by
   (      )                     / do this together
        *x                      / first element of x
       ,                        / append to
      x                         / x
    1_                          / drop first (ie rotate everything by 1)
 +/                             / sum, add (+) over (/)

Solusi naif:

Hapus semuanya dari string yang bukan angka (sambil juga mengonversi), ambil jendela geser 2-item, cari tahu apakah itu ganjil atau genap, terapkan add / kurangi seperlunya, lalu jumlahkan.

{+/((-;+)2!x).'2':(1+#x)#x^:(x-:48)^!10}

Cobalah online!

Catatan:

  • -4 byte terima kasih kepada @ngn karena cara yang lebih cerdas untuk memfilter input
  • -3 byte dengan menggunakan jendela geser daripada membentuk kembali
  • -9 byte porting solusi ngn (pendekatan non-naif)
streetster
sumber
1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
ngn
Saya menulis solusinya di q / kdb + kemudian diport ke OK ... mungkin bisa memeras beberapa byte lagi dari ini!
streetster
1
Saya memposting jawaban terpisah dalam ngn / k, jangan ragu untuk membawa ide dari sana. Saya pikir oK akan menjadi yang terpendek, karena parser saya adalah sampah saat ini - itu tidak menguraikan tugas modifikasi dengan benar. By the way, saya tidak menyadari ':sebagai "jendela geser" - menarik.
ngn
Anda sepertinya terbiasa dengan k. Jika Anda merasa ingin mendiskusikan hal-hal pemrograman vektor dengan orang-orang yang berpikiran sama atau hanya menonton kami berdebat - kami punya ruang obrolan ini . Sebagian besar olok-olok adalah tentang APL, tetapi k dan J juga pada topik.
ngn
2

Perl 6 , 41 byte

{2*sum rotate($!=.comb(/\d/))Z*(@$! X%2)}

Cobalah online!

Menggunakan logika yang sama dengan jawaban Jelly dylnan . Jumlah ini hanya digit yang mengikuti angka ganjil dan kemudian dikalikan dengan 2.

Jo King
sumber
2

Powershell, 80 78 76 byte

($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s

-2 byte terima kasih Neil dengan solusi Retina

-2 byte terima kasih AdmBorkBork

Skrip uji:

$f = {
($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s
}

&$f 'r5e6o9mm!/3708dvc'

Penjelasan

Pertama-tama: itu bisa menambahkan 2 * n jika digit sebelumnya ganjil, dan 0 jika digit sebelumnya genap.

($d="$args"-split'\D*'-ne'')+ # let $d is array contains digits only, each element is a digit
$d[0]|                        # apend first digit to the end of the array
?{                            # where for each digit
    $p-match'[13579]'         # predicate is 'previous digit is odd' (it is false on the first iteration because $p is null)
    $p=$_                     # let previous digit is current
}|
%{                            # for each digit matched to the predicate
    $s+=2*$_                  # add current digit multiply 2 to $s. 
}
$s                            # return sum

Ekstra, 99 byte

Terinspirasi oleh @Neil. Regex angka yang cocok hanya dengan 'digit sebelumnya ganjil'. Matchesadalah variabel otomatis .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s
mazzy
sumber
1
Simpan byte swap |?{$_}untuk -ne''dan yang lain dengan pindah $d="$args"-split'\D*'-ne''ke parens like ($d="$args"-split'\D*'-ne'')+$d[0].
AdmBorkBork
2

MATL , 18 17 byte

t4Y2m)!Ut1YSof)sE

Cobalah online!

(-1 byte berkat Luis Mendo / Giuseppe / keduanya!)

Penjelasan:

     % Implicit input
 t   % duplicate input
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc']
 4Y2 % push inbuilt literal, characters '0':'9'
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc' '0123456789']
 m)  % extract only characters from input that belong to '0':'9'
     % stack: ['5693708']
 !U  % transpose and convert each value from string to number
     % stack: [5 6 9 3 7 0 8]
 t   % duplicate that
 1YS % circular shift by 1
     % stack: [[5 6 9 3 7 0 8] [8 5 6 9 3 7 0]]
 o   % parity check - 1 for odd, 0 for even
     % stack: [[5 6 9 3 7 0 8] [0 1 0 1 1 1 0]]
 f   % find non-zero value indices in last array
     % stack: [[5 6 9 3 7 0 8] [2 4 5 6]]
 )   % index at those places in the first array
 s   % sum
 E   % multiply by 2
     % (implicit) convert to string and display

Ide dasarnya adalah bahwa angka yang mengikuti angka genap dapat diabaikan, sedangkan angka yang mengikuti angka ganjil digandakan - dan hasil akhirnya adalah jumlah dari nilai yang digandakan.

Saya tidak berpikir fsetelah pemeriksaan paritas oakan diperlukan, tetapi untuk beberapa alasan MATL tidak melihat array dari 0 dan 1 yang dihasilkan dari osebagai array logis, sebagai gantinya mengambil mereka sebagai indeks numerik dan indeks ke posisi 1dan end.

sundar - Pasang kembali Monica
sumber
Saya pikir Anda dapat menggunakan !Ubukan 48-. Transpos tampaknya tidak membahayakan di sini. ountuk doubleinput saja mod(...,2), jadi outputnya double. NaNTrik input yang bagus ! Jika itu dimaksudkan untuk menyelesaikan keluaran luar biasa dalam STDOUT, Dennis punya ide dan mungkin akan segera memperbaikinya
Luis Mendo
!Ubukannya48-
Giuseppe
@LuisMendo, Anda mengalahkan saya sampai pukul!
Giuseppe
@Giuseppe :-D :-D
Luis Mendo
Terima kasih keduanya, diedit. @LuisMendo Kapan tidak omemberikan output array logis kemudian - atau tidak? (Harus saya akui saya tidak pernah benar-benar melihat ke sistem tipe numerik MATLAB.) Dan ya, saya pikir NaNakan membuat sentinel yang bagus karena tidak mungkin menjadi input aktual di mana saja, tetapi bagus untuk mengetahui bahwa itu tidak akan diperlukan lebih lama lagi !
sundar - Reinstate Monica
2

K (ngn / k) , 33 byte

{+/(1_x,*x)*2*2!x:-48+x^x^,/$!10}

Cobalah online!

{ } adalah fungsi dengan argumen x

!10 adalah daftarnya 0 1 ... 9

$ konversikan ke string

,/ menggabungkan

x^artinya xtanpa apa yang di kanan

x^x^berarti xberpotongan dengan apa yang ada di sebelah kanan, yaitu hanya menyimpan digit darix

-48+kurangi 48, yang merupakan kode ASCII dari"0"

x: menetapkan ke x

2! mod 2

2* dikalikan dengan 2

1_x,*xadalah satu tetes: xdiikuti oleh yang pertama dari x; yaitu xdiputar ke kiri dengan satu langkah

+/ jumlah

ngn
sumber
2

Japt (v2.0a0), 25 19 byte

-6 byte terima kasih kepada Shaggy .

kè\D
íÈ°*2*Y°u}Ué)x

Coba di sini .

Ini berfungsi tanpa digit saat ini! Input adalah daftar karakter.

LegionMammal978
sumber
19 byte , termasuk beralih ke Japt v2. Namun, tidak senang dengan fungsi array x. Ping saya dalam obrolan jika Anda memiliki pertanyaan.
Shaggy
Tunggu, perhatikan saja bahwa ini tidak akan berfungsi sama sekali jika input tidak mengandung digit apa pun.
Shaggy
Juga, di mana sumber untuk v2.0a0, @Shaggy? Saya tidak dapat menemukannya di repo.
LegionMammal978
Ini v1 dan ini v2.
Shaggy
Jika Anda melewatkannya di obrolan, saya mendapatkan ini hingga 12 byte untuk Anda.
Shaggy
2

05AB1E , 12 9 byte

Menghemat 1 byte di atas metode naif dengan memanfaatkan trik paritas dylnan,
tersimpan 3 byte berkat Tn. Xcoder

þDÁ€ÉÏSO·

Cobalah online!

Penjelasan

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double
Emigna
sumber
Hmm, akan þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·atau þÀsþ€ÉÏSO·lulus semua kasus uji untuk -2 byte?
Tn. Xcoder
@ Mr.Xcoder: Ah, ya. Bagus! Kami bahkan dapat melakukannya þDÁ€ÉÏSO·untuk -3 :)
Emigna
1

Retina , 37 byte

(\d).*
$&$1
L$`(?<=[13579]\D*).
2**
_

Cobalah online! Penjelasan:

(\d).*
$&$1

Tambahkan duplikat dari digit pertama.

L$`(?<=[13579]\D*).

Cocokkan apa pun yang angka pertama sebelumnya aneh.

2**

Ubah semua kecocokan menjadi unary dan gandakan. (Non-digit diperlakukan sebagai nol.)

_

Ambil jumlahnya. Jika tidak ada kecocokan, maka ini menghasilkan nol sesuai kebutuhan.

Yang terbaik yang bisa saya lakukan di Retina 0.8.2 adalah 44 byte:

[^\d]

(.).*
$&$1
(?<![13579]).

.
$*
.
..
.

Cobalah online! Penjelasan:

[^\d]

Hapus yang bukan digit.

(.).*
$&$1

Tambahkan salinan digit pertama.

(?<![13579]).

Hapus digit yang tidak mengikuti digit aneh.

.
$*

Konversikan ke unary.

.
..

Gandakan mereka.

.

Ambil jumlahnya.

Neil
sumber
Saya khawatir hasilnya akan salah jika angka terakhir tidak aneh
mazzy
1
@ Mazzy Ketika Anda mengatakan digit terakhir, maksud Anda sebelum atau setelah menyalin digit pertama hingga akhir?
Neil
'sampai akhir'. langkah 'Tambahkan duplikat digit pertama' yang disalin hingga akhir? baik. keren. Terima kasih
mazzy
1

Jelly , 15 byte

fØDV€1ịṭƊ+_Ḃ?ƝS

Cobalah online!

Erik the Outgolfer
sumber
Saya harap Anda tidak keberatan jika saya meminjam1ịṭƊ
dylnan
1

JavaScript (ES6), 56 byte

Mengambil input sebagai array karakter.

s=>s.map(c=>1/c?r+=p*(p=c*2&2,n=n||c,c):0,n=p=r=0)|r+p*n

Cobalah online!

Berkomentar

s =>                     // given the input array s[]
  s.map(c =>             // for each character c in s[]:
    1 / c ?              //   if c is a digit:
      r +=               //     update r:
        p * (            //       p = either 0 or 2 (always 0 on the 1st iteration)
          p = c * 2 & 2, //       p = 0 if c is even, 2 if c is odd
          n = n || c,    //       if n is still equal to 0 (as an integer), set it to c
          c              //       compute p * c
        )                //     add the result to r
    :                    //   else:
      0,                 //     do nothing
    n = p = r = 0        //   n = first digit, p = previous digit, r = result
  )                      // end of map()
  | r + p * n            // compute the last operation with the 1st digit and add it to r
Arnauld
sumber
1

JavaScript (Node.js) , 85 84 83 82 byte

-1 byte berkat ovs

s=>(s.match(/\d/g)||[]).reduce((r,n,i,a)=>r+(+n)+a[a[++i]!=null?i:0]*-(1-n%2*2),0)

Cobalah online!

Mengambil input string, menemukan digit sebagai array karakter atau mengembalikan array kosong jika tidak ditemukan, dan kemudian menggunakan tipe paksaan untuk memastikan nilai ditambahkan / dikurangi dengan benar. Pencarian maju preincrements indeks dan menggunakan pemeriksaan nol untuk singkatnya, dan kemudian bagian terakhir memeriksa apakah angka ganjil atau genap untuk kemudian memaksa penambahan atau pengurangan (+ dan - adalah -, dll)

bluefinger
sumber
n-0bisa+n
ovs
Selamat datang di PPCG!
Conor O'Brien
1

R , 58 byte

function(x,y=strtoi(x[x%in%0:9]))sum(c(y[-1],y[1])*y%%2*2)

Cobalah online!

  • menggunakan trik paritas dylnan
  • -8 byte menerima vektor karakter, bukan string
  • -3 byte terima kasih kepada @Giuseppe
menggali semua
sumber
67 byte jika Anda tidak keberatan dengan arrayoutput.
Giuseppe
1
hmm sebenarnya Anda tidak dapat menggunakan produk titik karena array kosong xxxsehingga 68 byte dengan menggunakan perubahan dalam pengindeksan auntuk menghasilkan y.
Giuseppe
@ Giuseppe: dimodifikasi, terima kasih :)
digEmAll
@ Giuseppe: Saya meminta pendapat Anda karena Anda adalah pegolf-kode yang lebih bijaksana ... dari komentar tampaknya kita dapat menggunakan vektor karakter, dalam hal ini 61 byte dimungkinkan: Cobalah secara online! Bagaimana menurut anda ?
digEmAll
gunakan strtoibukan as.double, tapi ya, itu seharusnya baik-baik saja.
Giuseppe
0

Perl 5 , 48 byte

$;=$;[++$-%@;],$\+=$_%2?$_+$;:$_-$;for@;=/\d/g}{

Cobalah online!

Saya cukup suka bagaimana samar ini terlihat, tetapi itu adalah lingkaran yang cukup mudah di sekitar semua angka dalam string.

Dom Hastings
sumber
0

Julia 0,6 , 77 69 byte

s->(s=s.-'0';s=s[0.<=s.<=9];endof(s)>0?sum(2(s%2).*[s[2:end];s[]]):0)

Cobalah online!

sundar - Pasang kembali Monica
sumber
0

C Tajam 180 byte

Ini bukan golf yang bagus, lol.

s=>{var q=new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));q.Enqueue(q.First());int t,o=0;o=q.Dequeue();try{while(true){t+=o+(o%2==0?-1:1)*(o=q.Dequeue());}}catch{return t;}}

Tidak Disatukan:

var q = new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));
int t,o=0;

q.Enqueue(q.First());    
o=q.Dequeue();

try{
    while(true){
        t += o + (o%2==0?-1:1) * (o=q.Dequeue());
    }
}
catch {
    return t;
}
IEatBagels
sumber
0

Stax , 14 byte

ÿ←«4é■≥B▬ê→█T♥

Jalankan dan debug itu

Dibongkar, tidak diserang, dan dikomentari, sepertinya ini.

Vd|&    filter out non-digits
c|(\    zip into pairs after rotating right
F       for each digit pair
  B2%s  first-of-pair % 2, then swap top two stack elements
  eH*   eval digit as integer, double, then multiply
  +     add to running total

Jalankan yang ini

rekursif
sumber
0

JavaScript (ES6), 52 byte

s=>s.filter(t=>1/t&&~(a+=u*t,u=t%2),a=u=0)[0]*u+a<<1

Diharapkan input sebagai array karakter. Peringatan: Karena penggunaan bit-shifting, output memiliki batas atas2^31-1

Cobalah online!

Penjelasan

Pada dasarnya menggandakan jumlah digit mengikuti nilai ganjil.

s => s.filter(             // filter to preserve the first digit
    t =>
        1/t &&             // short-circuits if NaN
        ~(                 // coerce to truthy value
            a += u * t,    // adds value only if previous digit is odd
            u = t%2        // store parity of current digit
        ),
    a = u = 0
)[0]                       // first digit
* u + a
<< 1                       // bit-shift to multiply by 2 (also coerces a NaN resulting from a string devoid of digits to 0)
redundansi
sumber