Wyzwanie dotyczy odczytu losowych linii z potencjalnie dużego pliku bez wczytywania całego pliku do pamięci.
Wejście
Liczba całkowita n
i nazwa pliku tekstowego.
Wynik
n
wiersze pliku tekstowego wybrane losowo równomiernie bez zamiany.
Możesz założyć, że n
mieści się w zakresie od 1 do liczby linii w pliku.
Zachowaj ostrożność, próbkując n
losowo liczby z zakresu, w którym odpowiedź jest jednorodna. rand()%n
na przykład w C nie jest jednolity. Każdy wynik musi być równie prawdopodobny.
Zasady i ograniczenia
Każda linia pliku tekstowego będzie miała tę samą liczbę znaków i nie będzie więcej niż 80.
Twój kod nie może czytać żadnej zawartości pliku tekstowego, z wyjątkiem:
- Linie, które wyprowadza.
- Pierwszy wiersz, aby sprawdzić, ile znaków w wierszu znajduje się w pliku tekstowym.
Możemy założyć, że każdy znak w pliku tekstowym zajmuje dokładnie jeden bajt.
Zakłada się, że separatory linii mają długość 1 bajta. Rozwiązania mogą korzystać z 2-bajtowych separatorów długich linii tylko wtedy, gdy określają to. Możesz również założyć, że ostatnia linia jest zakończona separatorem linii.
Twoja odpowiedź powinna być kompletnym programem, ale możesz podać dane wejściowe w dowolny dogodny sposób.
Języki i biblioteki
Możesz użyć dowolnego języka lub biblioteki.
Notatki
Wystąpił problem z obliczeniem liczby linii w pliku. Jak oni wskazują w komentarzach, możesz wywnioskować to na podstawie rozmiaru pliku i liczby znaków w wierszu.
Motywacja
Na czacie niektórzy pytali, czy to naprawdę pytanie „Wykonaj X bez Y”. Tłumaczę to, aby zapytać, czy ograniczenia są niezwykle sztuczne.
Zadanie losowego próbkowania linii z dużych plików nie jest rzadkie i w rzeczywistości muszę je czasem wykonać. Jednym ze sposobów na to jest bash:
shuf -n <num-lines>
Jest to jednak bardzo wolne w przypadku dużych plików, ponieważ odczytuje się w całym pliku.
fseek
, a w innych niemożliwe. Ponadto, co jeśli n
jest większa niż liczba linii w pliku?
sum()
. Brak wczytywania pliku do pamięci jest wyraźnym i spójnym ograniczeniem, które nie jest w żaden sposób arbitralne. Można go przetestować z plikiem większym niż pamięć, którego nie można obejść z powodu różnic językowych. Zdarza się również, że ma zastosowania w świecie rzeczywistym (chociaż nie jest to konieczne w przypadku golfa ...).