Napisz program, który wypisuje całkowitą liczbę znaków i częstotliwość każdego znaku w jego źródle i wyniku. Musisz postępować zgodnie z formatem zilustrowanym w przykładzie.
Przykład
Jeśli twój kod był
abb1
Musiałby to być jego wynik
My source has 4 characters.
1 is "a"
2 are "b"
1 is "1"
Besides unquoted numbers, my output has 383 characters.
34 are "
"
79 are " "
63 are """
2 are "'"
2 are ","
4 are "."
2 are "1"
2 are "B"
2 are "I"
2 are "M"
39 are "a"
4 are "b"
6 are "c"
4 are "d"
38 are "e"
3 are "g"
5 are "h"
4 are "i"
4 are "m"
3 are "n"
8 are "o"
3 are "p"
2 are "q"
38 are "r"
12 are "s"
8 are "t"
7 are "u"
3 are "y"
It's good to be a program.
(Dane wyjściowe muszą przejść na standardowe wyjście.)
Zauważ na przykład, że dane wyjściowe zawierają dwa wielkie litery. Jeden za My
i jeden za 2 are "M"
. Musi to dotyczyć wszystkich znaków, aby wynik nie był w żaden sposób sprzeczny.
Niecytowane liczby są ignorowane na wyjściu, aby uniknąć niezadowalających zestawów częstotliwości. Na przykład 1 is "1"
jest niepoprawny, jeśli liczone są oba 1. Powinien przeczytać 2 are "1"
, ale wtedy jest tylko jeden 1.
Formatuj wyjaśnienia
„is” musi być użyte w przypadku wystąpienia pojedynczego znaku.
„are” musi być użyte w przypadku wielu wystąpień znaków.
„jest” nigdy nie powinno pojawiać się na liście znaków wyjściowych, ponieważ byłoby zbędne.
1 is 'Z'
odnosi się do samej litery Z, więc można usunąć całą linię.Trzy pełne zdania muszą występować w kolejności z listami częstotliwości znaków pomiędzy nimi (jak pokazuje przykład). Twoje wyjście zacznie się
My source...
i zakończy...be a program.
. Zauważ, że na końcu wyniku nie ma nowej linii.Same listy częstotliwości postaci mogą być w dowolnej kolejności.
Nowe linie liczą się jako jeden znak (w przypadku, gdy są \ r \ n).
Kontroler formatu
Poniższy skrypt w języku Python przyjmuje kod i jego dane wyjściowe jako ciągi i zapewnia, że dane wyjściowe nie są sprzeczne. Zapewnia przydatny komunikat o błędzie, jeśli coś jest nie tak. Możesz uruchomić go online pod adresem http://ideone.com/6H0ldu , rozwidlając go, zastępując ciąg KOD i WYJŚCIE, a następnie uruchamiając. Nigdy nie da fałszywych wyników pozytywnych ani negatywnych (zakładając, że jest wolny od błędów).
#Change the CODE and OUTPUT strings to test your program
CODE = r'''abb1'''
OUTPUT = r'''My source has 4 characters.
1 is "a"
2 are "b"
1 is "1"
Besides unquoted numbers, my output has 383 characters.
34 are "
"
79 are " "
63 are """
2 are "'"
2 are ","
4 are "."
2 are "1"
2 are "B"
2 are "I"
2 are "M"
39 are "a"
4 are "b"
6 are "c"
4 are "d"
38 are "e"
3 are "g"
5 are "h"
4 are "i"
4 are "m"
3 are "n"
8 are "o"
3 are "p"
2 are "q"
38 are "r"
12 are "s"
8 are "t"
7 are "u"
3 are "y"
It's good to be a program.'''
#######################################################
import re
amountPattern = r'(\d+) (is|are) "(.)"\n'
class IntrospectionException(Exception):
pass
def getClaimedAmounts(string, errorOnIs):
groups = re.findall(amountPattern, string, re.DOTALL)
for amount, verb, char in groups:
if verb == 'is':
if errorOnIs:
raise IntrospectionException('\'1 is "%s"\' is unnecessary' % char)
elif amount != '1':
raise IntrospectionException('At "%s", %s must use "are"' % (char, amount))
elif verb == 'are' and amount == '1':
raise IntrospectionException('At "%s", 1 must use "is"' % char)
amounts = {}
for amount, verb, char in groups:
if char in amounts:
raise IntrospectionException('Duplicate "%s" found' % char)
amounts[char] = int(amount)
return amounts
def getActualAmounts(string):
amounts = {}
for char in string:
if char in amounts:
amounts[char] += 1
else:
amounts[char] = 1
return amounts
def compareAmounts(claimed, actual):
for char in actual:
if char not in claimed:
raise IntrospectionException('The amounts list is missing "%s"' % char)
for char in actual: #loop separately so missing character errors are all found first
if claimed[char] != actual[char]:
raise IntrospectionException('The amount of "%s" characters is %d, not %d' % (char, actual[char], claimed[char]))
if claimed != actual:
raise IntrospectionException('The amounts are somehow incorrect')
def isCorrect(code, output):
p1 = r'^My source has (\d+) characters\.\n'
p2 = r'Besides unquoted numbers, my output has (\d+) characters\.\n'
p3 = r"It's good to be a program\.$"
p4 = '%s(%s)*%s(%s)*%s' % (p1, amountPattern, p2, amountPattern, p3)
for p in [p1, p2, p3, p4]:
if re.search(p, output, re.DOTALL) == None:
raise IntrospectionException('Did not match the regex "%s"' % p)
claimedCodeSize = int(re.search(p1, output).groups()[0])
actualCodeSize = len(code)
if claimedCodeSize != actualCodeSize:
raise IntrospectionException('The code length is %d, not %d' % (actualCodeSize, claimedCodeSize))
filteredOutput = re.sub(r'([^"])\d+([^"])', r'\1\2', output)
claimedOutputSize = int(re.search(p2, output).groups()[0])
actualOutputSize = len(filteredOutput)
if claimedOutputSize != actualOutputSize:
raise IntrospectionException('The output length (excluding unquoted numbers) is %d, not %d' % (actualOutputSize, claimedOutputSize))
splitIndex = re.search(p2, output).start()
claimedCodeAmounts = getClaimedAmounts(output[:splitIndex], False)
actualCodeAmounts = getActualAmounts(code)
compareAmounts(claimedCodeAmounts, actualCodeAmounts)
claimedOutputAmounts = getClaimedAmounts(output[splitIndex:], True)
actualOutputAmounts = getActualAmounts(filteredOutput)
compareAmounts(claimedOutputAmounts, actualOutputAmounts)
def checkCorrectness():
try:
isCorrect(CODE, OUTPUT)
print 'Everything is correct!'
except IntrospectionException as e:
print 'Failed: %s.' % e
checkCorrectness()
Punktacja
To jest golf golfowy. Zgłoszenie z najmniejszą liczbą postaci wygrywa. Zgłoszenia muszą przejść sprawdzanie formatu, aby były prawidłowe. Obowiązują standardowe luki, ale możesz czytać własny kod źródłowy i / lub kodować wyjście .
r'''CODE'''
).Odpowiedzi:
CJam - 189
Wypróbuj na http://cjam.aditsu.net/
Wynik:
źródło
Rubinowy, 269 (311, 367) znaków
Mam trzy różne rozwiązania tego problemu. Każdy z nich używa innego zestawu sztuczek:
„Właściwe” rozwiązanie, 367 znaków:
Najdłuższe rozwiązanie jest mniej więcej dowodem koncepcji, że można rozwiązać to wyzwanie bez żadnych sztuczek - i nie jest prawie w pełni golfem. Jest to prawdziwa quine (tzn. Generuje własny kod źródłowy zamiast czytać go z pliku) i faktycznie oblicza wszystkie liczby, które drukuje (długość kodu, długość wyjściowa, występowanie znaków). Ze względu na sposób działania quine cały kod musi znajdować się w jednym wierszu i wewnątrz literału łańcucha.
Dane wyjściowe częściowo zakodowane, 311 znaków:
Następne najkrótsze rozwiązanie wykorzystuje dwie sztuczki, ale nadal jest prawdziwym quine: - W kodzie źródłowym nie występuje dokładnie jeden znak. W ten sposób nie muszę decydować, czy mam wydrukować,
is
czyare
w pierwszej połowie wydruku. Ułatwia to również obliczenie całkowitego rozmiaru wyjściowego (chociaż tak naprawdę nie muszę tego robić). - Całkowity rozmiar wyjściowy jest zakodowany na stałe. Ponieważ zależy to tylko od liczby różnych znaków w kodzie źródłowym (oraz w ogólnym przypadku, ile z tych znaków występuje tylko raz), łatwo jest je wcześniej obliczyć.Zauważ, że kod poprzedza dwie bardzo znaczące nowe znaki, których StackExchange nie pokazałby w bloku kodu. Z tego powodu dodałem dodatkowy wiersz z przodu, jeśli te nowe znaki, które nie są częścią kodu.
Najkrótsze rozwiązanie, 269 znaków:
Najkrótsze rozwiązanie dodatkowo koduje własną długość źródła. Używając nazw zmiennych, które nie są jeszcze częścią kodu źródłowego, można znaleźć „punkt stały”, w którym wszystkie znaki w kodzie źródłowym (w tym cyfry z zakodowanych długości!) Występują co najmniej dwa razy.
To rozwiązanie pozwala również zaoszczędzić kilka dodatkowych znaków, po prostu czytając własny kod źródłowy z pliku kodu, zamiast go generować. Jest to miły efekt uboczny, który sprawia, że kod jest znacznie bardziej „czytelny” (ale kogo to obchodzi o czytelnym kodzie w golfie kodowym ...), ponieważ teraz kod nie musi już być wewnątrz literału łańcucha.
Zmodyfikowałem też trochę skrypt testowy, aby zmniejszyć ilość wklejanych kopii potrzebnych do sprawdzenia kodu. Zastępując definicje
CODE
iOUTPUT
zskrypt automatycznie uruchamia teraz mój kod, odczytuje jego dane wyjściowe i pobiera kod źródłowy z pliku kodu.
Oto wynik wygenerowany przez najkrótszy kod:
źródło