Skip to content

Instantly share code, notes, and snippets.

@richardjharris
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save richardjharris/f53c1ea136c1e18b2a14 to your computer and use it in GitHub Desktop.

Select an option

Save richardjharris/f53c1ea136c1e18b2a14 to your computer and use it in GitHub Desktop.
# JLPT N1 question parser. Type 'q' or Ctrl+C to quit.
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
use Getopt::Long;
use Scalar::Util qw(looks_like_number);
my $question_file = 'JLPT1 Questions.txt';
my $start = 1;
GetOptions(
'question-file=s' => \$question_file,
'start=i' => \$start,
) or die("Invalid arguments");
binmode STDOUT, ':utf8';
my @questions = load_questions($question_file);
for my $q (@questions) {
next if $start && $q->{number} < $start;
print "Question #$q->{number}:\n";
print $q->{question}, "\n";
my $selected_answer = prompt($q->{answers});
my $correct_answer_text = $q->{answers}[$q->{correct_answer} - 1];
if ($selected_answer == $q->{correct_answer}) {
print "CORRECT! The answer is $correct_answer_text\n";
my $correct_sentence = $q->{question};
$correct_sentence =~ s/( +)/($correct_answer_text)/;
print $correct_sentence, "\n";
}
else {
print "Sorry,that's wrong? Try again!\n";
redo;
}
}
sub load_questions {
my $question_file = shift or die "missing question file";
my @questions;
open my $fh, '<:encoding(utf8)', $question_file or die "open: $!";
my $number = 1;
while (my $line = <$fh>) {
my $question = {};
$line =~ s/^\x{FEFF}//; # Remove possible UTF-8 BOM (why the fuck?)
$line =~ /\A(\d+\s*)?(.*?)\Z/ or die "invalid question '$line'";
if (!$1 || $1 <= 100) {
# Question does not include answers, skip
next;
}
$question->{number} = $number++;
$line = $2;
# Sometimes answers are included inline.
if ($line =~ s/\s*1\)(.*?) 2\)(.*?) 3\)(.*?) 4\)(.*)?\Z//) {
$question->{question} = $line;
$question->{answers} = [$1,$2,$3,$4];
}
else {
$question->{question} = $line;
$line = <$fh>;
$question->{answers} = [$line =~ /\A1\)(.*?) 2\)(.*?) 3\)(.*?) 4\)(.*)?\Z/];
}
$question->{answers} = [ map { s/^\s*//; s/\s*$//; $_ } @{$question->{answers}} ];
$line = <$fh>;
$line =~ /\A答案:(\d+)\s*\Z/ or die "no answer? $line";
$question->{correct_answer} = $1;
push @questions, $question;
}
return @questions;
}
sub prompt {
my @opts = @{$_[0]};
my $answer;
for my $i (0..$#opts) {
printf "%d) %s\n", $i + 1, $opts[$i];
}
LOOP: while (1) {
print "Answer: ";
$answer = <STDIN>;
if (looks_like_number($answer) && $answer > 0 && $answer <= @opts) {
last LOOP;
}
elsif ($answer =~ /^q/i) {
exit;
}
else {
print "Invalid answer, try again!\n";
}
}
return $answer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment