Putar kamera; simpan seorang Astronaut


23

Catatan: Spoiler kecil untuk Mars ada dalam tantangan ini. Baca terus dengan hati-hati


The Marsian adalah novel Fiksi Ilmiah tentang astronot dan ahli botani luar biasa, Mark Watney , yang secara tidak sengaja terdampar di Mars. Pada satu titik dalam buku itu, Mark mencoba berkomunikasi dengan NASA, tetapi satu-satunya alat komunikasi yang mereka miliki adalah kamera. Mark mengirim pesan dengan menulis pada kartu indeks, dan, karena NASA dapat memutar kamera 360 derajat, NASA mengirim balasan dengan mengarahkan kamera ke kartu yang berlabel "Ya" atau "Tidak".

Karena satu-satunya data yang dapat dikirimkan NASA adalah arah yang dihadapi kamera, Markus muncul dengan sistem di mana mereka dapat menunjuk kartu dengan karakter alfabet pada mereka untuk mengetik pesan. Tetapi menggunakan huruf 'az' tidak praktis. Mengutip buku (dari jawaban ini , di atas scifi.se):

Kita perlu berbicara lebih cepat daripada pertanyaan ya / tidak setiap setengah jam. Kamera dapat berputar 360 derajat, dan saya punya banyak bagian antena. Saatnya membuat alfabet. Tapi aku tidak bisa hanya menggunakan huruf A sampai Z. Dua puluh enam huruf plus kartu pertanyaan saya akan menjadi dua puluh tujuh kartu di sekitar pendarat. Masing-masing hanya akan mendapatkan 13 derajat busur. Bahkan jika JPL menunjukkan kamera dengan sempurna, ada kemungkinan saya tidak akan tahu huruf apa yang dimaksud.

Jadi saya harus menggunakan ASCII. Begitulah cara komputer mengelola karakter. Setiap karakter memiliki kode numerik antara 0 dan 255. Nilai antara 0 dan 255 dapat dinyatakan sebagai 2 digit heksadesimal. Dengan memberi saya pasangan angka hex, mereka dapat mengirim karakter apa pun yang mereka suka, termasuk angka, tanda baca, dll.

...

Jadi saya akan membuat kartu untuk 0 hingga 9, dan A hingga F. Itu membuat 16 kartu untuk ditempatkan di sekitar kamera, ditambah kartu pertanyaan. Tujuh belas kartu berarti masing-masing lebih dari 21 derajat. Jauh lebih mudah untuk dihadapi.

Tujuan Anda hari ini, sebagai salah satu insinyur perangkat lunak top di NASA, adalah menulis program untuk menyandikan berbagai sudut kamera. Tujuh belas kartu yang Mark miliki untuk Anda tunjukkan adalah (dalam urutan):

?0123456789ABCDEF

dan masing-masing kartu ini berjarak 21 derajat, jadi untuk memutar kamera dari ?ke 0, Anda harus memutar kamera 21 derajat, dan 2menjadi 1-21 derajat. (Ini tidak persis 21, tapi kami akan mengumpulkan untuk tetap sederhana) membungkus ini, sehingga untuk pergi dari Fke 3adalah 105 derajat (5 putaran, 5 * 21 = 105). Ini lebih efisien daripada pergi -252, karena kamera tidak perlu bergerak sejauh ini.

Inilah yang harus dilakukan oleh program atau fungsi Anda.

  1. Ambil string sebagai input. Kami akan memanggil string ini s . Sederhananya, kami akan mengatakan bahwa input hanya akan dapat dicetak ASCII. Sebagai contoh kita, katakanlah inputnyaSTATUS

  2. Konversi setiap karakter ke representasi heksadesimalnya. Ini akan dikonversi STATUSmenjadi 53 54 41 54 55 53.

  3. Mencetak atau mengembalikan derajat berturut-turut yang perlu dilakukan kamera untuk menunjuk pada setiap kartu dan kembali ke "Kartu Pertanyaan". Sebagai contoh kita, ini akan menjadi:

    6  * 21 = 126   (?-5)
    -2 * 21 = -42   (5-3)
    2  * 21 = 42    (3-5)
    -1 * 21 = -21   (5-4)
    0  * 21 = 0     (4-4)
    -3 * 21 = -63   (4-1)
    4  * 21 = 84    (1-5)
    -1 * 21 = -21   (5-4)
    1  * 21 = 21    (4-4)
    0  * 21 = 0     (5-5)
    0  * 21 = 0     (5-5)
    -2 * 21 = -42   (5-3)
    -4 * 21 = -84   (3-?)
    

    Atau, dalam format array:

    [126, -42, 42, -21, 0, -63, 84, -21, 21, 0, 0, -42, -84]
    

Perhatikan bahwa Anda harus selalu mengambil rotasi terkecil dari kemungkinan. Jadi jika inputnya adalah NO, yaitu 4E 4F, Anda harus menampilkan:

5    * 21 = 105
-7   * 21 = -147
7    * 21 = 147
-6   * 21 = -126
1    * 21 = 21

Daripada:

 5   * 21 = 105
 10  * 21 = 210
 -10 * 21 = -210
 11  * 21 = 231
 -16 * 21 = -336

Berikut adalah beberapa contoh yang dikerjakan:

Input: CROPS?
ASCII: 43 52 4F 50 53 3F
Worked Example:

5  * 21 = 105
-1 * 21 = -21
2  * 21 = 42
-3 * 21 = -63
2  * 21 = 42
-6 * 21 = -126
7  * 21 = 147
-5 * 21 = -105
5  * 21 = 105
-2 * 21 = -42
0  * 21 = 0
-5  * 21 = -105
1 * 21 = 21

Result: [105 -21 42 -63 42 -126 147 -105 105 -42 0 -105 21]


Input: DDD
ASCII: 44 44 44
Worked Example:

5   * 21 = 105
0   * 21 = 0
0   * 21 = 0
0   * 21 = 0
0   * 21 = 0
0   * 21 = 0
-5  * 21 = -105

Result: [105, 0, 0, 0, 0, 0, -105]


Input: Hello world!
ASCII: 48 65 6c 6c 6f 20 77 6f 72 6c 64 21
Worked example:

5   * 21 = 105
4   * 21 = 84
-2  * 21 = -42
-1  * 21 = -21
1   * 21 = 21
6   * 21 = 126
-6  * 21 = -126
6   * 21 = 126
-6  * 21 = -126
-8  * 21 = -168
4   * 21 = 84
-2  * 21 = -42
7   * 21 = 147
0   * 21 = 0
-1  * 21 = -21
-8  * 21 = -168
-8  * 21 = -168
-5  * 21 = -105
4   * 21 = 84
6   * 21 = 126
-6  * 21 = -126
-2  * 21 = -42
-2  * 21 = -42
-1  * 21 = -21
-2  * 21 = -42

Result: [105 84 -42 -21 21 126 -126 126 -126 -168 84 -42 147 0 -21 -168 -168 -105 84 126 -126 -42 -42 -21 -42]

Karena NASA membanggakan efisiensi, tujuan Anda adalah menulis kode sesingkat mungkin. Celah standar berlaku. Sekarang bawa dia pulang!


Catatan: Kasus-kasus uji ini dibuat dengan tangan, dan agak menyebalkan, jadi mungkin ada beberapa ketidakakuratan minor. Tolong beri tahu saya jika ada yang tidak beres. :)
DJMcMayhem

Jawaban:


5

JavaScript (ES6), 103 99 byte

s=>[...s.replace(/./g,c=>c.charCodeAt().toString(16)),10].map(n=>((24-p-~(p='0x'+n))%17-8)*21,p=-1)

Uji kasus


Apakah ini akan berhasil? s.replace(/./g,->[...s].map(
Luke

@ Lukas Tidak, karena kita perlu memisahkan setiap digit heksadesimal. ...s.replace(/./g,memberi misalnya "4","8","6","5","6","c"..., sementara. ...[...s.map(akan memberikan"48","65","6c",...
ETHproduk

4

C, 212 202 199 187 byte

3 byte disimpan berkat @KritixiLithos!

i;f(a,b){i=abs(a-b);i=8>i?i:17-i;i=a<b&a>b-8?i:a<b&a<b-8?-i:b<a&b>a-8?-i:i;i*=21;}v;g(char*s){for(v=0;*s;s+=v++%2)printf("%d ",v?v%2?f(*s%16,s[1]?s[1]/16:-1):f(*s/16,*s%16):f(-1,*s/16));}

Cobalah online!


1
Saya pikir Anda bisa melakukan 8>i?i:17-ialih - alih17-i>i?...
Kritixi Lithos

@KritixiLithos ya, terima kasih.
betseg

3

Python, 187 178 byte

def g(x):w,z=map('?0123456789abcdef'.index,x);d=w-z;return min(d,d+17*(d<=0 or -1),key=abs)*21
def f(s):s=''.join(map('{:2x}'.format,s.encode()));return[*map(g,zip(s+'?','?'+s))]

Uji kasus

for k in ['STATUS', 'NO', 'CROPS?', 'DDD', 'Hello world!']:
    print('Input:  {}\nOutput: {}'.format(k, f(k)))


1

Jelly , 21 19 byte

Ob⁴F-;;-I+8%17_8×21

Cobalah online!

Bagaimana?

Ob⁴F-;;-I+8%17_8×21 - Main link: string s        e.g. 'e.g.'
O                   - cast to ordinals            [101,     46,       103,      46]
 b                  - convert to base
  ⁴                 -     16                   [[6,   5], [2,  14], [6,   7], [2,  14]]
   F                - flatten                   [6,   5,   2,  14,   6,   7,   2,  14]
    -;              - -1 concatenate      [-1,   6,   5,   2,  14,   6,   7,   2,  14]
      ;-            - concatenate -1      [-1,   6,   5,   2,  14,   6,   7,   2,  14,  -1]
        I           - increments            [  7,  -1,  -3,  12,  -8,   1,  -5,  12, -15]
         +8         - add 8                 [ 15,   7,   5,  20,   0,   9,   3,  20,  -7]
           %17      - mod 17                [ 15,   7,   5,   3,   0,   9,   3,   3,  10]
              _8    - subtract 8            [  7,  -1,  -3,  -5,  -8,   1,  -5,  -5,   2]
                ×21 - multiply by 21        [147, -21, -63,-105,-168,  21,-105,-105,  42]

1

Ohm , 20 19 byte (CP437), tidak bersaing

EDIT : Disimpan 1 byte dengan mengubah blok peta menjadi peta komponen tunggal yang diulang.

Mungkin akan sedikit lebih pendek jika saya memiliki vektorisasi implisit.

`»x»}{»úΓXΓHδ▓_~21*

Penjelasan:

`»x»}{»úΓXΓHδ▓_~21*    Main wire, arguments: s

`»x                    Convert char codes of s to hex
   »}                  Split digit pairs
     {                 Flatten
      »ú               Convert digits back to base 10
        ΓXΓH           Append and prepend with -1
            δ          Get deltas between each element of array
             ▓         Map array over...
              _~21*      Negate, multiply by 21

0

PHP, 125 116 byte:

function m($i){static$a;$a+=$d=($i-$a+10)%17-9;echo$d*21,"
";}for(;$c=ord($argv[1][$i++]);m($c%16))m($c/16|0);m(-1);

kerusakan

function m($i)              // function to turn camera:
{
    static$a;                   // remember angle
    $a+=                        // add delta to angle
    $d=($i-$a+10)%17-9;         // delta: target=nibble value+1-current angle
                                // add 9, modulo 17, -9 -> shortest movement
    echo$d*21,"\n";                 // print delta * 21 and a linebreak
}
for(;$c=ord($argv[1][$i++]);// loop through input characters
    m($c%16))                   // 2. move to low nibble value
    m($c/16|0)                  // 1. move to high nibble value
;
m(-1);                      // move back to "?"

Tentu saja, 21cukup tidak akurat dan mungkin gagal untuk string yang lebih panjang dari 14 karakter; tapi kemudian ... 360/17akan empat byte lebih lama.

Solusi alternatif seharusnya dengan memasang laser pointer ke kamera;
kita bisa menggunakan semua karakter ascii yang dapat dicetak dan kartu "pertanyaan" dengan masing-masing 3,75 derajat.

Alternatif lain: Gunakan 16 kartu (pada 22,5 derajat) dengan 6 karakter masing-masing:
menerapkan semacam T9 dan kita dapat menghilangkan nibble yang tinggi. ;)

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.