Utwórzmy siatkę N × N spacji i znaków podkreślenia, których można użyć do wizualnego ustalenia, czy liczba jest liczbą pierwszą. (N może być dowolną liczbą całkowitą dodatnią).
Ta siatka ma trzy proste zasady:
- N-ta kolumna zawiera powtarzający się wzór n-1 znaków podkreślenia, po których następuje jedna spacja. Ten wzorzec zaczyna się w pierwszym rzędzie i jest zatrzymany, być może w połowie wzorca, w rzędzie N. (Rzędy i kolumny mają indeks 1).
- Pierwsza kolumna zostaje zastąpiona wszystkimi znakami podkreślenia zamiast wszystkich spacji.
- Jeśli gdzieś występuje spacja, indeks wiersza jest równy indeksowi kolumny, zostaje on zastąpiony znakiem podkreślenia.
Przykład: N = 10
1
1234567890 <-- column indices
1__________
2__________
3__________
4_ ________
5__________
6_ _______
7__________
8_ _ ______
9__ _______
10_ __ _____
^ row indices
Wskaźniki służą wyłącznie przejrzystości. Sama zwykła siatka (co program musi wypisać) to:
__________
__________
__________
_ ________
__________
_ _______
__________
_ _ ______
__ _______
_ __ _____
Zauważ, że:
- Pierwsza kolumna to wszystkie podkreślenia.
- Druga kolumna to spacja podkreślenia, spacja podkreślenia itp., Z wyjątkiem podkreślenia w wierszu 2.
- Trzecia kolumna zawiera znak podkreślenia, znak podkreślenia itp., Z wyjątkiem podkreślenia w wierszu 3.
- itp.
Zauważ również, że oprócz 1 tylko wiersze z liczbami pierwszymi mają podkreślenia w każdej kolumnie.
Ponieważ podkreślenia obejmują całą szerokość czcionki, każdy wiersz z liczbą pierwszą tworzy ciągłą ciągłą linię. Zatem sprawdzenie, czy liczba jest liczbą pierwszą, czy nie, jest dość łatwe wizualnie; po prostu sprawdź, czy jego linia jest ciągła we wszystkich kolumnach. (W rzeczywistości wystarczy spojrzeć na pierwiastek kwadratowy z indeksu wierszy, ale generowanie siatki wydaje się mniej eleganckie).
Program
Napisz program, który narysuje te siatki, otrzymując N poprzez stdin (lub najbliższą alternatywę). Dane wyjściowe są kierowane na standardowe wyjście (lub najbliższą alternatywę) i powinny zawierać tylko spacje, podkreślenia i znaki nowej linii, z opcjonalnym znakiem końca linii.
Najkrótszy kod wygrywa.
n
wierszu th zmieńk
znak th na spację, jeślik
jest dzielnikiem,m
który nie jest równy 1 lubm
.Odpowiedzi:
CJam,
332827 bajtówWypróbuj online.
Jak to działa
Przykładowy przebieg
źródło
Ruby,
7773 znakówNiektóre sztuczki, których użyłem:
..
Operator ma prawie najniższy priorytet wszystkich operatorów w Ruby, tak(1..n=gets.to_i)
właśnie działa.Zamiast dodawać dodatkowy
a!=1
warunek podczas sprawdzania, czy znak powinien być spacją zamiast podkreślenia (ponieważ pierwszy wiersz to wszystkie podkreślenia), właśnie zacząłem zakres2
i dodałem dodatkowy?_
.Linia A może stać się linią B:
ponieważ muszę mieć dodatkową spację między
b
i?
w linii A, ale to nie jest potrzebne między0
i?
w linii B.b?
jest prawidłową metodą Rubiego, ale0?
nie jest.puts
automatycznie dołączy do tablic z nowymi liniami, eliminując potrzebę dodatkowych*"\n"
.Dane wyjściowe dla
n=100
:Teraz w tym Extra-Special ™ Mega-kolorowy czerwony © Highlight-Magic ™ ® Extended Edition ©: (kliknij miniaturkę, aby powiększyć)
Rubinowy z kolorem, 110 znaków
źródło
' '
. Prawdopodobnie psuje twój zakreślacz składni, ale nadal działa poprawnie. Ponadto,a%b<1
*''
będzie działał tak samo jak złączenie i możesza<b
zamiast tego sprawdzić,a!=b
ponieważ żaden współczynnik a nie jest większy niż a. Oszczędności mogą też wynikać z krojenia na dwuznakowy ciąg z wynikiem pewnej matematyki na a i b zamiast używania trójskładnika.J - 28 znaków
Wyjaśnione przez wybuch:
Jak to wygląda:
źródło
Python 2,
7671Nie wiem, czy to może dostać każdy krótszy niż ten ... Te słowa kluczowe:
range
,input
aprint
kosztują sporo.źródło
i>j>1and i%j<1
zi>j>1>i%j
i%j<1<j<i
:-P. Więc może naprawdę nie jest krótszy.i%j<1
. To implikujei>=j
.i>j
, a niei>=j
do uniknięcia półfabrykatów na przekątnej.APL (28)
Wyjaśnienie:
⍳2⍴⎕
: odczytaj liczbę N i utwórz macierz współrzędnych N-na-N(
...)/¨
: dla każdej pary współrzędnych zastosuj następującą funkcję:0=|⍨
: ymod
x = 0 i≠
: x nie jest równe y, i1≠⊢
: x nie jest1
.1+
: Dodaj1
do wynikowej macierzy bitów, ponieważ tablice APL zaczynają się od 1.'_ '[
...]
: zastąp każdy1
znakiem podkreślenia i2
spacją.źródło
Perl,
6961Zaktualizowana wersja (dzięki, Dennis !)
Orginalna wersja:
źródło
join
nie są2..$n
potrzebne. 2. Za pomocą-n
przełącznika możesz użyć$_
zamiast$n
. 3._
jest prawidłowym gołym słowem, więc nie wymaga cudzysłowów. 4. Możesz użyć$"
zamiast" "
. 5. Możesz użyć|
zamiast||
.-n
, ponieważ chciałem, aby był to samodzielny program i nie musiałem mówić$^N=1
. Użycie słowa_
kluczowego działało w przypadku,$i==_
ale nie działało w przypadku,$i%_
ponieważ parser myślał, że%_
to skrót.#!/bin/perl -n
zwykle jest liczony jako 1 bajt), ale to oczywiście zależy od ciebie. Nie mam pojęcia, co$^N=1
działa ... 2.$i==_
nie działa poprawnie; sprawdzi, czy$i == "_"
. Chodziło mi o to stosując_
zamiast"_"
, czylisay _
a$i==$_?_:$"
._
="_"
teraz. Niestety, działa w tym drugim przypadku, ale wyświetla błąd obok,say
ponieważ wydaje się, że jest to uchwyt pliku.CJam, 27 bajtów
Wypróbuj online.
Podejście to osiąga taką samą liczbę bajtów, jak moja inna odpowiedź, ale pomyślałem, że i tak warto to opublikować. Zamiast oznaczać odpowiednie wielokrotności w każdym rzędzie, robi dokładnie to, co mówi specyfikacja.
Jak to działa
Przykładowy przebieg
źródło
C 143
C nie jest oczywiście dobrym wyborem do tego celu. Ale dla kompletności, oto jeden możliwy sposób, aby to zrobić w C. Działa dla wartości od n do 1048575. Odczytuje n ze standardowego wejścia.
Jest jednak bardzo szybki.
Czas działania dla n = 1 000 000 (co daje siatkę 1 000 000 000 000 elementów) wynosi w moim systemie około 55 minut.
Czas działania dla n = 1000 (który wytwarza siatkę o wartości 1 000 000 elementów) jest krótszy niż 1/100 sekundy.
źródło
int
, dzięki czemu można ich używaćchar x[1<<20];n,i,j;main...
. 3.for(scanf("%d",&n);i++<n;)
oszczędza dwa bajtyscanf("%d",&n);for(;++i<=n;)
.