Ekspansi Biner Biner


9

Biasanya, kami menguraikan angka menjadi angka biner dengan menetapkannya dengan kekuatan 2, dengan koefisien 0atau 1untuk setiap istilah:

25 = 1*16 + 1*8 + 0*4 + 0*2 + 1*1

Pilihan 0dan 1... tidak terlalu biner. Kami akan melakukan ekspansi biner yang sebenarnya dengan memperluas dengan kekuatan 2, tetapi dengan koefisien 1atau -1sebaliknya:

25 = 1*16 + 1*8 + 1*4 - 1*2 - 1*1

Sekarang ini terlihat biner.

Dengan angka positif, sepele untuk melihat bahwa:

  • Setiap angka ganjil memiliki banyak sekali ekspansi biner sejati
  • Setiap angka genap tidak memiliki ekspansi biner yang benar

Oleh karena itu, agar ekspansi biner yang benar dapat didefinisikan dengan baik, kami membutuhkan ekspansi yang paling kecil , yaitu dengan panjang terpendek.


Dengan bilangan bulat positif, ganjil n, kembalikan ekspansi biner yang sebenarnya, dari digit paling signifikan ke digit paling tidak signifikan (atau dalam urutan terbalik).

Aturan:

  • Karena ini adalah , Anda harus melakukan ini dalam hitungan byte sesingkat mungkin. Dibangun secara bawaan.
  • Output apa pun yang dapat mewakili dan daftar koefisien dapat diterima: array, serangkaian koefisien dengan pemisah, dll ...
  • Berlaku celah golf standar.
  • Program Anda harus bekerja untuk nilai-nilai dalam ukuran integer standar bahasa Anda.

Uji Kasus

25 -> [1,1,1,-1,-1]
47 -> [1,1,-1,1,1,1]
1 -> [1]
3 -> [1,1]
1234567 -> [1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1]

Terkait tetapi sangat berbeda.
Giuseppe

4
Algoritma sederhana: Konversikan ke basis 2, ganti 0 dengan -1, letakkan LSD di depan.
Josiah Winslow

Voile: Saya tidak menjelaskan downvotes, saya hanya menjabarkan algoritma untuk orang-orang yang memiliki perintah konversi basis dalam bahasa mereka.
Josiah Winslow

Karena Anda sangat ingin menjadi biner, dapatkah kami mengembalikan nilainya sebagai bit yang dikemas dengan nilai tempat biasa tetapi interpretasi baru kedua negara? yaitu elektrik itu hanya tegangan tinggi atau rendah (atau apa pun), dan itu bukan kesalahan saya jika cetak standar debugger 0bukan -1untuk keadaan tegangan rendah. Penelepon yang menerima bit tahu apa artinya. (Ini masih merupakan latihan manipulasi bit non-sepele, karena hak putar hanya berfungsi jika memiliki 32 bit signifikan. Mis. Angka 5-bit membutuhkan lebar putar 5.)
Peter Cordes

Apakah output perlu menyertakan pemisah? Apakah 111-1-1output yang valid untuk 25?
Oliver

Jawaban:


7

Japt , 6 byte

¤é r0J

Cobalah online!

Penjelasan:

¤é r0J  // Test input:                  25
¤       // Binary the input:            11001
 é      // Rotate 1 chars to the right: 11100
   r0J  // Replace 0s with -1:          111-1-1

1
Ah, rotasi; itu sebabnya itu tidak berhasil untuk saya.
Shaggy

2
Memutar??? dagnabbit.
Giuseppe

3

Pyth ,  12  11 byte

|R_1.>jQ2 1

Coba di sini!


Bagaimana?

| R_1.> JQ2 1 Program lengkap.

      jQ2 Mengonversi input ke daftar biner.
     .> 1 Putar secara siklus daftar di atas dengan 1 tempat ke kanan.
| R_1 Pengganti 0 dengan -1.
               Keluaran tersirat.

Pertama, kita perhatikan bahwa tugasnya hanyalah "mengganti 0huruf s dalam biner dengan huruf -1s dan bergeser ke kanan dengan 1 tempat." - Itulah tepatnya yang harus kita lakukan! Konversi biner memberi kita daftar 0s dan 1s. Semua harus kita lakukan di sini adalah untuk menemukan cara Golfy untuk mengkonversi 0ke -1. Operator bitwise |(bitwise OR) adalah teman kami. Peta di atas representasi biner bergeser dengan |dan -1. Jika nomor saat ini 0, itu akan dikonversi ke -1.


Saya tidak berpikir ada cara yang lebih baik. ;)
Josiah Winslow

@JosiahWinslow I do ... Mencoba menemukannya
Tn. Xcoder

Hm? Algoritme tampaknya optimal, mungkin itu karena saya tidak tahu Pyth.
Josiah Winslow

@JosiahWinslow Menemukan cara yang lebih baik. Cara sintaksis yang lebih baik, bukan cara algoritmik yang lebih baik.
Tn. Xcoder

@ Mr.Xcoder Dan sekarang benar-benar tidak ada sama sekali bagi saya.
Erik the Outgolfer


3

JavaScript (ES6), 35 34 byte

f=n=>n?[...f(n>>=1),!n|n%2||-1]:[]

Cuplikan tes


2

Perl 6 , 72 byte

Pasti ada cara yang lebih baik, tetapi inilah yang saya miliki ...

->$a {grep {$a==[+] @^a.reverse Z+< ^∞},[X] (1,-1)xx $a.base(2).chars}

Cobalah online!

Penjelasan : Ini adalah fungsi yang membutuhkan satu argumen ( ->$a). Kami pertama-tama mendapatkan jumlah koefisien yang dibutuhkan ( $a.base(2).chars= jumlah karakter dalam representasi basis 2), kemudian membuat produk Cartesian ( X) dari banyak pasangan itu (1,-1). ( [X]Berarti: kurangi daftar berikut dengan X.) Jadi, kami mendapatkan daftar semua kemungkinan kombinasi 1s dan -1s. Kemudian kami memfilter ( grep) hanya daftar yang menyandikan nomor yang diberikan $a. Hanya ada satu, jadi kami mendapatkan daftar satu daftar dengan koefisien.

Blok grep melakukan ini: mengambil argumennya sebagai daftar ( @^a), membalikkannya dan menutupnya dengan daftar tanpa batas 0,1,2,...menggunakan operator "shift bit kiri" +<. Zipping berhenti segera setelah daftar pendek habis (baik untuk kita!) Kami kemudian menjumlahkan semua hasil dan membandingkannya dengan nomor yang diberikan. Kami harus menggunakan .reversekarena OP menuntut agar koefisien berada dalam urutan dari yang paling signifikan hingga yang tidak signifikan.




1

J, 11 byte

1-~2*_1|.#:

Cobalah online!

Terima kasih kepada @JosiahWinslow untuk algoritmenya.

Adakah pemikiran untuk mempersingkat konversi? Pikiranku adalah menggunakan !.-fit (nvm, itu hanya mengubah toleransi konversi).

Menggunakan {-membawa lebih lama dengan 1 karakter.

_1 1{~_1|.#:

1

Java 8, 101 byte

n->{String s=n.toString(n,2);return(s.charAt(s.length()-1)+s.replaceAll(".$","")).replace("0","-1");}

Port dari @Oliver 's Japt answer , dengan beberapa byte lagi ..;)

Pasti bisa bermain golf dengan menggunakan pendekatan matematika, bukan pendekatan String ini.

Penjelasan:

Coba di sini.

n->{                             // Method with Integer parameter and String return-type
  String s=n.toString(n,2);      //  Convert the Integer to a binary String
  return(s.charAt(s.length()-1)  //  Get the last character of the binary String
    +s.replaceAll(".$","")       //   + everything except the last character
   ).replace("0","-1");          //  Then replace all zeroes with -1, and return the result
}                                // End of method

1

R , 90 88 46 byte

function(n)c((n%/%2^(0:log2(n))%%2)[-1],1)*2-1

Cobalah online!

Menerapkan algoritma Oliver , tetapi mengembalikan digit dalam urutan terbalik. Karena kami dijamin ntidak pernah genap, bit yang paling tidak signifikan (pertama) selalu 1, jadi kami menghapusnya dan menambahkan 1sampai akhir untuk mensimulasikan rotasi dalam R. Terima kasih kepada Shaggy karena membuat saya memperbaiki matematika saya .

Cukup dengan menempatkan rev( )fungsi panggilan di footer harus mengembalikan nilai dalam urutan yang sama.

jawaban asli, 88 byte:

function(n,b=2^(0:log2(n)))(m=t(t(expand.grid(rep(list(c(-1,1)),sum(b|1))))))[m%*%b==n,]

Fungsi anonim; mengembalikan nilai dalam urutan terbalik dengan nama kolom terlampir.

Cobalah online!

Penjelasan:

function(n){
 b <- 2^(0:log2(n))         # powers of 2 less than n
 m <- expand.grid(rep(list(c(-1,1)),sum(b|1))) # all combinations of -1,1 at each position in b, as data frame
 m <- t(t(m))               # convert to matrix
 idx <- m%*%b==n            # rows where the matrix product is `n`
 m[idx,]                    # return those rows
}

Saya tidak akan menganggap output itu valid; sarankan untuk meminta konfirmasi kepada penulis tantangan.
Shaggy

@Shaggy membalikkan urutan diizinkan secara eksplisit: from the most significant digit to the least significant digit (or in reversed order).karenanya ini harus dapat diterima.
Giuseppe

1
Terbalik agar , tidak terbalik tanda-tanda. Berarti output yang valid untuk 25, misalnya, akan [1,1,1,-1,-1]atau [-1,-1,1,1,1].
Shaggy

1
@ Shaggy ah, Anda benar, saya baru saja salah menghitung! seharusnya 2*bits - 1bukan 1-2*bits. Terima kasih.
Giuseppe




0

Golfscript, 14 13 14 byte

-1 byte karena saya lupa %ada. +1 byte karena saya juga lupa input adalah string.

~2base{.+(}%)\

1
Jika Anda akan menganggap bahwa input datang sebagai bilangan bulat, Anda harus membungkus kode {}untuk membuatnya menjadi blok. Program lengkap hanya bisa mendapatkan input sebagai string.
Peter Taylor

Um ... apa? Maksud saya, nomor tersebut didorong sebagai bilangan bulat, bukan string yang berisi angka.
Josiah Winslow

Jika demikian, jawaban Anda bukan program lengkap, dan sebagainya harus berupa "fungsi" , atau dalam kasus GolfScript, blok. Karena itu {2base{.+(}%\}untuk 15 byte. Demikian pula jawaban CJam Anda.
Peter Taylor

Ini adalah program lengkap. Input dalam Golfscript secara implisit didorong ke stack pada awal program, dan input dalam CJam ditentukan sebelum eksekusi dan diakses dengan perintah q.
Josiah Winslow

Saya memiliki sedikit keakraban dengan GolfScript . ( Dan CJam ). Jika Anda ingin mengklaim bahwa ini adalah program lengkap, Anda harus membuatnya awalan ~.
Peter Taylor
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.