To pytanie jest inspirowane tą odpowiedzią . Przypadkowo, kiedy byłem dzieckiem, używałem mnożenia etnicznego, ale do niedawna nie znałem nazwy tej metody.
Etiopskie mnożenie to metoda mnożenia liczb całkowitych przy użyciu tylko dodawania, podwajania i zmniejszania o połowę.
Metoda:
- Weź dwie liczby do pomnożenia i zapisz je u góry dwóch kolumn.
- W lewej kolumnie kilkakrotnie zmniejsz o połowę ostatnią liczbę, odrzucając resztki i zapisz wynik poniżej ostatniej w tej samej kolumnie, aż zapiszesz wartość 1.
- W prawej kolumnie wielokrotnie powtarzaj ostatnią liczbę i wpisz wynik poniżej. zatrzymaj się, gdy dodasz wynik w tym samym wierszu, w którym w lewej kolumnie pokazuje 1.
- Sprawdź wyprodukowaną tabelę i odrzuć każdy wiersz, w którym wartość w lewej kolumnie jest parzysta. Zsumuj wartości w prawej kolumnie, które pozostały, aby uzyskać wynik pomnożenia dwóch oryginalnych liczb.
Na przykład: 17 x 34
17 34
Zmniejszenie o połowę pierwszej kolumny:
17 34
8
4
2
1
Podwojenie drugiej kolumny:
17 34
8 68
4 136
2 272
1 544
Przekreśl wiersze, których pierwsza komórka jest parzysta, zrobimy to, umieszczając liczby po prawej stronie w nawiasach kwadratowych:
17 34
8 [68]
4 [136]
2 [272]
1 544
Zsumuj pozostałe liczby w prawej kolumnie:
17 34
8 [68]
4 [136]
2 [272]
1 544
=====
578
Zatem 17 pomnożone przez 34, metodą etiopską jest 578.
Zadanie:
Kod golfowy, który przyjmuje dwie liczby od 1 do 1000 i wykonuje ten sam układ i algorytm, wyświetlając produkt poniżej.
Metoda wprowadzania: jednak wybierasz ...
Przykładowe dane wejściowe:
19 427
Wynikowy wynik:
19 427
9 854
4 [1708]
2 [3416]
1 6832
======
8113
Zwróć uwagę na wyrównanie cyfr. Jest to najważniejsze w układzie. Zauważ również, że podwójna linia ułożona znakami równości musi być o dwa znaki dłuższa niż ogólna odpowiedź i musi być wyśrodkowana.
Testowanie
Jak będziesz to testować? Udostępniając przebieg programu za pomocą dwóch liczb. Liczby te można wyodrębnić z numeru identyfikacyjnego użytkownika (można to uzyskać, najeżdżając kursorem na awatar w górnym oknie). Weź swój numer i weź trzy ostatnie cyfry, będzie to liczba B, weź wszystko, co pozostanie z przodu, to będzie liczba A. Następnie sprawdź A razy B.
Przykład testowy:
Mój numer identyfikacyjny użytkownika to 8555, więc moje numery to 8 i 555. Więc moje dane wyjściowe powinny wyglądać następująco:
8 [555]
4 [1110]
2 [2220]
1 4440
======
4440
Ograniczenia:
Żadne natywne operatory mnożenia nie są dozwolone, z wyjątkiem „podwajania”, jak wspomniano w algorytmie. Innymi słowy, jeśli używasz operatora takiego jak *, można go użyć tylko do pomnożenia przez 2.
Zgłoszenia niezgodne z powyższym nie będą brane pod uwagę, a użytkownik zostanie wyprowadzony z lokalu z tekturowym pudełkiem pełnym swoich rzeczy. Każdy wpis będzie miał kod plus test oparty na numerze identyfikacyjnym użytkownika.
To jest kod golfowy. Najmniejsza liczba bajtów otrzyma nagrodę, chwałę i podziw swoich rówieśników ... (A może Lamborghini ... Powiedziałem „może”!)
*
lubx
), ale nie można wykryć, czy używane jest mnożenie. Oprócz tej części wyzwanie jest interesujące.Odpowiedzi:
Węgiel drzewny , 91 bajtów
Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:
Ustawia
t
na pustą listę is
na0
. (u
domyślnie jest to pusta lista).Wprowadza dwie liczby.
Powtarza się, gdy
q
jest niezerowy.Zawiń
q
padding i dodaj go do listyt
.Zawiń
h
w wypełnienie lub w[]
zależności od tego, czyq
jest nieparzysty, i dołącz go do listyu
.Dodaj
h
dos
jeśliq
jest nieparzyste.Liczba całkowita podziel
q
przez 2.Dodaj
h
do siebie.Dodaj odpowiedni ciąg
=
znaków do listyu
.Dołącz wyściełaną sumę
s
do listyu
.Obróć listę
t
o 180 ° i wydrukuj ją do góry nogami, w ten sposób uzasadniając ją.Przesuń kursor, aby w przypadku
u
wyrównania do prawej jego lewy górny róg wyrównał się z prawym górnym narożnikiem, do którego właśnie dotarliśmy, i wydrukuj wyrównanie dou
prawej.źródło
Python 2 ,
203202187133 bajtówWypróbuj online!
Jeśli mogę użyć
*
do mnożenia ciągów ('='*R
) i jako „selektora” (b*(a%2)
zamiast[0,b][a%2]
), otrzymuję:118 bajtów
Wypróbuj online!
Wyjaśnienie:
źródło
Java (OpenJDK 8) ,
353316267214210 bajtówWypróbuj online!
źródło
(a,b)->{int g=0;for(;a>0;g+=a%2*b,a/=2,b*=2)System.out.printf("%1$8d%2$10s\n",a,a%2<1?"["+b+"]":" "+b+" ");System.out.printf("%1$19s%2$18s","".valueOf(new char[(int)Math.log10(g)+3]).replace("\0","=")+"\n",g+" ");}
a%2*b
miłe i proste, dziękujęMathematica, 264 bajty
Wejście
wynik
źródło
s=Quotient[s,2]
Perl 5 , 157 bajtów
155 bajtów kodu + 2 flagi wiersza poleceń (
-nl
)Wypróbuj online!
źródło
JavaScript 2017, 221 bajtów
Głównie problem z formatowaniem wyjściowym
Mniej golfa
Test
źródło
C, C ++,
319313301299 bajtów-8 bajtów dzięki Zacharýowi
Wielkie dzięki
printf
magii właśnie nauczyłem się w 60 minut między edycjamiOptymalizacja C ++ zastąpić nagłówek
stdio.h
przezcstdio
istring.h
przezcstring
, oszczędza 2 bajtKompilacja z MSVC wymaga dodania
#pragma warning(disable:4996)
w celu użyciasprintf
Testowanie przy użyciu mojego identyfikatora PPCG:
72 x 535 =>
Przestrzega zasad, cyfry są wyrównane, a znaki równości zawsze będą o 2 znaki większe niż końcowa liczba. Przykład z 17 x 34 =>
źródło
#define O printf("%*d %c%*d%c\n",5,a,a%2?' ':'[',9,b,a%2?' ':']');
ivoid m(int a,int b){int r=0,i=0;O while(a>1){r+=a%2*b;a/=2;b*=2;O}r+=b;char t[20],p[20];memset(t,0,20);memset(p,0,20);sprintf(t,"%d",r);for(;i<strlen(t)+2;++i)p[i]='=';printf("%*c%*s\n%*d",5,' ',12,p,16,r);}
%
i*
są takie same, więcr+=a%2*b
powinno działać.[Bash],
144142140131128 bajtówLepszy szacunek wyświetlania, zauważ, że jest spacja
Pierwsza odpowiedź
źródło
Haskell , 305 bajtów
Wypróbuj online!
!
Operator tworzy dwie listy,?
oblicza produkt.%
i#
są używane do układu ascii.źródło
C,
205201190183156150143 bajtówSpowoduje to kompilację z ostrzeżeniami jako C89 i nie sądzę, że jest to poprawny C99, ale ostatecznie jest mniejszy niż wersja HatsuPointerKun, ponieważ oszczędza bajty przez ominięcie
#include
, nie używając dynamicznych długości do printf, ponieważ są niepotrzebne, i za pomocąlog10()
do obliczenia liczby=
potrzebnych:Jak mój numer to
64586
, użyłem tego programu testowego do obliczenia64 * 586
:i wyprowadza:
edytować
zapisane 4 bajty według reguły „domyślnej int”
edycja 2
zapisano 11 bajtów, przechodząc do
do...while()
pętli i przenosząc printf do pętli z makra. Powinien również działać poprawnie, jeślia=1
.edycja 3
zapisałem 7 bajtów i poprawiłem działanie kodu.
edycja 4
Zaoszczędzono 26 bajtów dzięki pewnym sztuczkom związanym z printf.
edycja 5
zaoszczędzono 6 bajtów, składając dodatkowe wypełnienie w 1 cyfrę.
edycja 6
zapisano 7 bajtów przez trickf printf z operatorem trójskładnikowym i nie deklarując nieużywanej zmiennej
źródło
Excel VBA, 183 bajty
Anonimowa funkcja bezpośredniego okna VBE, która pobiera dane wejściowe z zakresu
[A1:B1]
i dane wyjściowe do konsoli.Bez golfa
Wynik
źródło