Schrödinger's Laser


24

Küçük evcil hayvanlar üzerinde deney yapmaktan bıkmış olan Nobel, ödüllü Erwin Schrödinger, en yakın lazeri bulmaya ve bunun yerine çekim yapmaya karar verdi. Çünkü ... bilim!

Açıklama

İki lazer geçtiğini noktaları ve bir lazer ışınının boyutu verilecek ve lazer ışını yeri belirlemek gerekir gerekir , gitmiş olabilir gitmiş ve olamazdı gitti.

Lazer ışını yatay, dikey veya çapraz olabilir. Boyut 1 lazer ışını için, sırasıyla şöyle görünürler:

       #  #
       #   #
#####  #    #
       #     #
       #      #

Çapraz lazer ışını da çevrilebilir. Boyut 2 lazer ışınları şöyle görünür:

       ###  ##
#####  ###  ###
#####  ###   ###
#####  ###    ###
       ###     ##

Genel olarak, (n) boyutlu bir lazer ışını elde etmek için, basitçe lazer ışınını (n-1) alın ve her iki tarafa da bir lazer boyutlu (1) lazer ışını ekleyin. Son bir örnek olarak, işte aynı "tahta" da gösterilen 3 büyüklüğünde olası lazer ışınları.

###.....#####.....##
####....#####....###
#####...#####...####
.#####..#####..#####
..#####.#####.#####.
...###############..
....#############...
.....###########....
####################
####################
####################
####################
####################
.....###########....
....#############...
...###############..
..#####.#####.#####.
.#####..#####..#####
#####...#####...####
####....#####....###

Bu "tahta" her zaman 20x20 (karakter cinsinden) boyutlara sahip olacaktır.

Giriş

Programınıza girdi olarak beş tam sayı verilecektir. Sırayla, x 1 , y 1 , x 2 , y 2 ve lazer ışınının boyutlarıdır. Tam olarak bu sırada alınmaları gerekir. İsterseniz, sıralı (x, y) çiftlerini bir dizi, sıra, liste ya da iki değeri saklayan diğer dahili veri türü olarak alabilirsiniz.

Girdi olarak verilen iki puanın her ikisi de pano içerisinde olacaktır ve farklı olmaları garanti edilir (yani iki puan asla aynı olmaz). Lazer ışınının boyutu buna bağlıdır 1 ≤ size < 20. Her iki noktadan geçen en az bir olası lazer ışını her zaman olacaktır.

Çıktı

Programınız, aşağıdaki karakterlerden 20x20'lik bir ızgara çıkarmalıdır:

  • # iki noktadan geçen her lazer ışını da bu noktadan geçerse.
  • . iki noktadan geçen ve bu noktadan geçen bir lazer ışını yoksa.
  • ? Olası lazer ışınlarından bazıları (tümü değil) bu noktadan geçerse.
  • Xeğer bu iki orijinal giriş noktasından biriyse (bu geçersiz kılar #).

Test durumları

7, 7, 11, 3, 1

..............#.....
.............#......
............#.......
...........X........
..........#.........
.........#..........
........#...........
.......X............
......#.............
.....#..............
....#...............
...#................
..#.................
.#..................
#...................
....................
....................
....................
....................
....................

18, 18, 1, 1, 2

#??.................
?X??................
??#??...............
.??#??..............
..??#??.............
...??#??............
....??#??...........
.....??#??..........
......??#??.........
.......??#??........
........??#??.......
.........??#??......
..........??#??.....
...........??#??....
............??#??...
.............??#??..
..............??#??.
...............??#??
................??X?
.................??#

10, 10, 11, 10, 3

?????..????????..???
??????.????????.????
????????????????????
????????????????????
.???????????????????
..??????????????????
????????????????????
????????????????????
????????????????????
????????????????????
??????????XX????????
????????????????????
????????????????????
????????????????????
????????????????????
..??????????????????
.???????????????????
????????????????????
????????????????????
??????.????????.????

3, 3, 8, 10, 4

??????????..........
??????????..........
??????????..........
???X??????..........
???##?????..........
???###????..........
????###????.........
.????###????........
..????###????.......
..?????##?????......
..??????X??????.....
..??????????????....
..???????????????...
..????????????????..
..?????????????????.
..??????????????????
..??????????????????
..????????.?????????
..????????..????????
..????????...???????

Test senaryoları, dikey alanı korumak için bir Stack Snippet'in içinde bulunan aşağıdaki Ruby komut dosyası ile oluşturuldu.

kurallar

  • Programınız her bir test senaryosunu 30 saniyenin altında bir sürede çözebilmelidir (makul bir makinede). Bu daha çok bir akıl sağlığı kontrolünden geçiyor, çünkü test Ruby programım tüm test durumlarını anında çözdü.

  • Bu , bu yüzden en kısa çözüm kazanır.


2
Burada kullanılan terminoloji başlangıçta beni tetikledi. Lazerin normalde lazer ışınları üreten bir cihazı ifade ettiğine inanıyorum . Burada temsil ettiğin şey gerçekten de kirişler, değil mi? Bunun, ışınım üreten cihaz olan gerçek lazerin bir temsili olması gerekmiyor mu?
Reto Koradi

2
Son test durumu yanlış görünüyor. 4 boyutlu bir lazer 9 piksel genişliğinde olmalıdır. Dikey iz en az bu kadar geniş olmalıdır, ancak gerçekte daha dardır.
Seviye Nehri St

1
@steveverrill Boyut 4, 7 piksel genişliğindedir. Piksel cinsinden genişlik 2 * size - 1. 1 büyüklüğü 1 piksel, 2 büyüklüğü 3 piksel, 3 büyüklüğü 5 piksel (yukarıdaki örneğe bakın), 4 büyüklüğü 7 pikseldir.
Reto Koradi

2
Schrodinger'in bu zorlukla nasıl bir bağlantısı olduğunu anlamıyorum.
user12205,

1
@JonasDralle Yine, zaman sınırı çoğunlukla sadece bir akıl sağlığı kontrolüdür ve neredeyse her başvurunun bundan çok daha kısa sürede tamamlanması beklenmektedir.
Kapı tokmağı

Yanıtlar:


5

C 291 280 277 265 bayt

x,y,A,C,B,D,a,c,b,d,w,s,t;T(i){return abs(i)<2*w-1;}U(j,k){s+=T(j-k)*T(j)*T(k);t*=T(j-k)*j*k<1;}main(){for(scanf("%i%i%i%i%i",&a,&b,&c,&d,&w);y<20;y+=!x)s=0,t=1,U(A=a-x,C=c-x),U(B=b-y,D=d-y),U(A-B,C-D),U(A+B,C+D),putchar((x=++x%21)?".?#x"[!!s+t+(!A*!B+!C*!D)]:10);}

Kullanılarak derlenebilir / çalıştırılabilir:

gcc laser.c -o lazer & & echo "10 10 11 10 3" | ./lazer

Aşağıda, boşluk ve açıklayıcı yorumlarla aynı kod:

// Integers...
x,y,A,C,B,D,a,c,b,d,w,s,t;

// Is true if i is in range (of something)
T(i){return abs(i)<2*w-1;}

// Tests if lasers (horizontal, vertical, diagonal, etc) can/must exist at this point
// T(j-k) == 0 iff the laser of this direction can exist
// s += 1 iff this laser direction can pass through this point
// t *= 1 iff this laser direction must pass through this point
U(j,k){
    s+=T(j-k)*T(j)*T(k);
    t*=T(j-k)*j*k<1;
}

main(){ 
    // Read input; p0=(a,b), p1=(c,d)
    for(scanf("%i%i%i%i%i",&a,&b,&c,&d,&w); y<20; y+=!x)

        // A, B, C and D represent delta-x and delta-y for each points
        // e.g.: if we're processing (2,3), and p0=(4,5), A=4-2, B=5-3
        // s != 0 iff (x,y) can have some laser through it
        // t == 1 iff all lasers pass through (x,y)
        // (!A*!B+!C*!D) == 1 iff (x,y) is either p0 or p1  
        s=0,t=1,U(A=a-x,C=c-x),U(B=b-y,D=d-y),U(A-B,C-D),U(A+B,C+D),
        putchar((x=++x%21)?".?#x"[!!s+t+(!A*!B+!C*!D)]:10);
}

1
U(int j,int k)-> U(j,k); '\n'-> 10.
user12205,

1
k<=0->k<1
user12205

Güzel nokta. Yapabilseydim çok oy kullanırdım!
André Harder,

4

C, 302 bayt

b[400],x,y,s,t,w,d,e,g,k;f(u,v){d=u*x+v*y;e=u*s+v*t;if(e<d)k=e,e=d,d=k;for(k=0;k<400&d+w>e;++k)g=k%20*u+k/20*v,b[k]|=g>e-w&g<d+w|(g<d|g>e)*2;}main(){scanf("%d%d%d%d%d",&x,&y,&s,&t,&w);w=2*w-1;f(1,0);f(0,1);f(1,1);f(1,-1);b[y*20+x]=4;b[t*20+s]=4;for(k=0;k<400;)putchar(".#.?X"[b[k]]),++k%20?0:puts("");}

Girilen değer stdin'den tanımlanır ve 5 rakam okunur.

Son boyut küçültme adımından önce:

#include <stdio.h>
#include <stdlib.h>

int b[400], x, y, s, t, w, d, e, g, k;

void f(int u, int v) {
  d = u * x + v * y;
  e = u * s + v * t;
  if (e < d) k = e, e = d, d = k;
  if (d + w > e) {
    for (k = 0; k < 400; ++k) {
      g = u * (k % 20) + v * (k / 20);
      if (g > e - w && g < d + w) b[k] |= 1;
      if (g < d || g > e) b[k] |= 2;
    }
  }
}

int main() {
  scanf("%d%d%d%d%d", &x, &y, &s, &t, &w);
  w = 2 * w - 1;
  f(1, 0); f(0, 1); f(1, 1); f(1, -1);
  b[y * 20 + x] = 4;
  b[t * 20 + s] = 4;
  for (k = 0; k < 400; ) {
     putchar(".#.?X"[b[k]]);
     ++k % 20 ? 0 : puts("");
  }
}

Anahtar adımların bazı açıklamaları:

  • Dizi b, durumu / sonucu tutar. Bir ışın ile ulaşılabilen tüm pikseller için bit 0 ayarlanacaktır. Bit 1 olan tüm pikseller için ayarlanacaktır değil tüm kirişlerle kaplı.
  • fonksiyon f 4 yönün tümü için çağrılır (dikey, yatay, her iki köşegen). Argümanları, yönün normal vektörünü belirtir.
  • İşlevinde f :
    • Her iki giriş noktasının yöne göre mesafesi hesaplanır ( dvee , normal vektörün geçtiği noktanın nokta ürünü olarak ).
    • Gerekirse mesafeler değiştirilir, böylece ddaima eşit veya daha küçük olur.e .
    • Eğer arasındaki dve arasındaki egenişlik arasındaki fark daha büyükse, bu yönde hiçbir ışın mümkün değildir.
    • Aksi takdirde, tüm piksellerin üzerinde döngü yapın. Piksel herhangi bir ışın tarafından erişilebilir durumdaysa bit 0 ve tüm ışınlar tarafından kaplanmamışsa bit 1'i ayarlayın.
  • İki giriş noktasını 4 değeriyle işaretleyin. 0 ve 3 değerlerine neden olan durumu izlemek için 0 ve 1 bitlerini kullandığımızdan, bu en küçük kullanılmayan değerdir.
  • İçindeki piksellerin üzerinde döngü yapın bve 0 - 4 arasındaki değerleri yazdırırken karşılık gelen karakterlerine dönüştürün.

son kod satırını bu fordöngüdeki
Charles
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.