我們的目标是讓Perl社群參與知識共享。你可能會發現一些挑戰太簡單了,但你可以嘗試用一種别人從未想過的方式來解決它,那将是你的驕傲時刻。我們盡量讓挑戰變得簡單,這樣越來越多的人可以參與進來,并向其他人學習。在挑戰結束時,來自所有成員的解決方案将被推送到github存儲庫。
最後但并非最不重要的是,如果你對未來的挑戰有任何建議,請與我們分享。祝你好運,玩得開心。
挑戰#1
編寫一個腳本或一行代碼删除正數的前導0。
C語言
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
int main (void) {
char * line = NULL;
size_t len = 0;
size_t strlen;
while ((strlen = getline (&line, &len, stdin)) != -1) {
printf ("%lld\n", atoll (line));
}
free (line);
return (0);
}
Go語言
package main
import (
"fmt"
)
func main () {
var i int;
for {
var n, err = fmt . Scanf ("%d", &i)
if n != 1 || err != nil {
break
}
fmt . Println (i)
}
}
Java
import java.util.*;
public class ch1 {
public static void main (String [] args) {
Scanner scanner = new Scanner (System . in);
while (scanner . hasNextInt ()) {
System . out . println (scanner . nextInt ());
}
}
}
Bash
shopt -s extglob
while read number
do echo "${number##+(0)}"
done
Lua
for line in io . lines () do
io . write (tonumber (line), "\n")
end
Node.js
require ('readline')
. createInterface ({input: process . stdin})
. on ('line', _ => console . log (+_));
Pascal
var
i: LongInt;
begin
while not eof do begin
readln (i);
writeln (i);
end
end.
Perl
use 5.032;
use strict;
use warnings;
no warnings 'syntax';
use experimental 'signatures';
use experimental 'lexical_subs';
say 0 + $_ for <>;
Python
import fileinput
for line in fileinput . input ():
print (int (line))
R語言
stdin <- file ('stdin', 'r')
repeat {
n <- readLines (stdin, n = 1)
if (length (n) == 0) {
break
}
n = as.integer (n)
cat (n, "\n")
}
Ruby
ARGF . each_line do |_|
puts _ . to_i
end
挑戰#2
編寫一個腳本,使用字元0-9和a - y在整數和base35(35進制)表示之間進行轉換。如果你需要一些背景知識,Dave Jacoby對base35的描述很好。
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>
int BASE = 35;
long long from_base (char * number) {
long long out = 0;
while (* number) {
char ch = * number ++;
int n = ch <= '9' ? ch - '0' : ch - 'A' + 10;
out *= BASE;
out += n;
}
return (out);
}
char * to_base (long long number) {
char * out;
if ((out = (char *) malloc (64 * sizeof (char))) == NULL) {
fprintf (stderr, "Out of memory\n");
exit (1);
}
size_t i = 0;
while (number > 0) {
int rest = number % BASE;
out [i ++] = rest < 10 ? '0' + rest
: 'A' + rest - 10;
number = number / BASE;
}
out [i] = '\0';
for (size_t j = 0; 2 * j < i; j ++) {
char t = out [j];
out [j] = out [i - j - 1];
out [i - j - 1] = t;
}
return (out);
}
int main (int argc, char ** argv) {
char * line = NULL;
size_t len = 0;
size_t strlen;
int do_to_base = 0;
int do_from_base = 0;
char ch;
while ((ch = getopt (argc, argv, "tf")) != -1) {
switch (ch) {
case 't':
do_to_base = 1;
break;
case 'f':
do_from_base = 1;
break;
}
}
if (do_to_base + do_from_base != 1) {
fprintf (stderr, "Need exactly one of -f or -t options\n");
exit (1);
}
while ((strlen = getline (&line, &len, stdin)) != -1) {
line [strlen - 1] = '\0'; /* Chop off newline */
if (do_from_base) {
printf ("%lld\n", from_base (line));
}
if (do_to_base) {
char * out = to_base (atoll (line));
printf ("%s\n", out);
free (out);
}
char * line_ptr = line;
}
free (line);
return (0);
}
Go語言
package main
import (
"fmt"
"flag"
"bufio"
"os"
"strconv"
"strings"
)
func main () {
to_base := flag . Bool ("t", false, "a bool")
from_base := flag . Bool ("f", false, "a bool")
flag . Parse ()
var reader = bufio . NewReader (os. Stdin)
for {
var line, err = reader . ReadString ('\n')
if (err != nil) {
break
}
line = strings . Trim (line, "\n")
if *from_base {
i, err := strconv . ParseInt (line, 35, 0)
if (err == nil) {
fmt . Println (i)
}
}
if *to_base {
i, err := strconv . ParseInt (line, 10, 0)
if (err == nil) {
fmt . Println (strings . ToUpper (strconv . FormatInt (i, 35)))
}
}
}
}
Java
import java.util.*;
public class ch2 {
public static void main (String [] args) {
Boolean from_base = false;
Boolean to_base = false;
if (args . length == 1) {
if (args [0] . equals ("-f")) {
from_base = true;
}
if (args [0] . equals ("-t")) {
to_base = true;
}
}
Scanner scanner = new Scanner (System . in);
while (scanner . hasNextLine ()) {
String line = scanner . nextLine () . trim ();
if (from_base) {
System . out . println (Integer . parseInt (line, 35));
}
if (to_base) {
System . out . println (Integer . toString (
Integer . parseInt (line), 35) .
toUpperCase ());
}
}
}
}
Bash
set -f
printf -v ord_0 %d "'0"
printf -v ord_A %d "'A"
while getopts "ft" opt
do case "${opt}" in
f) action=from ;;
t) action=to ;;
esac
done
function from_base_35 () {
local in=$1
local ord
local char
base_10=0
for ((i = 0; i < ${#in}; i ++))
do ((base_10 = 35 * base_10))
char=${in:$i:1}
printf -v ord %d "'$char"
if [[ $char =~ [0-9] ]]
then ((base_10 = base_10 + ord - ord_0))
else ((base_10 = base_10 + ord - ord_A + 10))
fi
done
}
function to_base_35 () {
local in=$1
base_35=""
while ((in > 0))
do ((rem = in % 35))
((in = in / 35))
if ((rem > 9))
then printf -v char "\x$(printf %x $((ord_A + rem - 10)))"
else char=$rem
fi
base_35=${char}${base_35}
done
}
while read line
do if [[ "$action" = from ]]
then from_base_35 $line; echo $base_10
else to_base_35 $line; echo $base_35
fi
done
Lua
local do_to_base = 0
local do_from_base = 0
local BASE = 35
--
-- 解析選項,如果不正确則退出
--
if #arg == 1
then if arg [1] == "-f"
then do_from_base = 1
end
if arg [1] == "-t"
then do_to_base = 1
end
end
if do_to_base + do_from_base ~= 1
then io . stderr : write ("Need exactly one of '-f' or '-t'\n")
os . exit (1)
end
--
-- 建立一個數組,将10進制的數字映射為35進制的數字,反之亦然
--
local digits = {}
for i = 0, 9 do
digits [i] = i
digits [i .. ""] = i
end
for i = 10, BASE - 1 do
local char = string . char (65 + i - 10);
digits [char] = i;
digits [i] = char;
digits [i .. ""] = char;
end
--
-- Take a (base 10) number, turn it to a base 35 number
--
function to_base (number)
local out = ''
while number > 0 do
local n = number % BASE
out = digits [n] .. out
number = math . floor (number / BASE)
end
return out
end
--
-- 将一個35進制的數字(字元串)轉換為10進制的數字
--
function from_base (number)
local out = 0
for char in number : gmatch "." do
out = out * BASE + tonumber (digits [char])
end
return out
end
--
-- 周遊輸入,根據指令行選項調用to_base/from_base。
--
for line in io . lines () do
if do_to_base == 1
then io . write (to_base (tonumber (line)), "\n")
else io . write (from_base (line), "\n")
end
end
Node.js
let BASE = 35
//
// 使用yargs子產品解析選項
//
const argv = require ('yargs')
. option ('from_base', {
alias: 'f',
type: 'boolean',
})
. option ('to_base', {
alias: 't',
type: 'boolean',
})
. argv;
//
// 檢查選項
//
if ((argv . to_base ? 1 : 0) + (argv . from_base ? 1 : 0) != 1) {
console . log ("Requires exactly one of '-f' or '-t'")
process . exit (1)
}
//
// 設定數字,将base-10數字映射為base-35數字,反之亦然
//
let digits = {};
for (let i = 0; i < 10; i ++) {
digits [i] = i
}
for (let i = 10; i < BASE; i ++) {
let char = String . fromCharCode (65 + i - 10)
digits [char] = i
digits [i] = char
}
//
//換算成35進制
//
function to_base (number) {
let out = "";
while (number) {
let n = number % BASE
out = digits [n] + out
number = Math . floor (number / BASE)
}
return out
}
//
// 轉換自 base 35
//
function from_base (base) {
let out = 0
base . split ('') . forEach (c => {
out = BASE * out + digits [c]
})
return out
}
//
//周遊輸入,根據參數-f或-t對每一行調用to_base或from_base。
//
require ('readline')
. createInterface ({input: process . stdin})
. on ('line', _ => console . log (argv . to_base ? to_base (+ _)
: from_base (_ . trim ())))
;
Pascal
uses
strutils;
var
line: string;
num: longint;
to_base, from_base: boolean;
begin
if paramCount () = 1 then begin
if paramStr (1) = '-f' then begin
from_base := true;
end;
if paramStr (1) = '-t' then begin
to_base := true;
end
end;
while not eof do begin
if to_base then begin
readln (num);
writeln (Dec2Numb (num, 1, 35));
end;
if from_base then begin
readln (line);
writeln (Numb2Dec (line, 35));
end
end
end.
Perl
use 5.032;
use strict;
use warnings;
no warnings 'syntax';
use experimental 'signatures';
use experimental 'lexical_subs';
use Getopt::Long;
GetOptions ('t' => \my $to_base,
'f' => \my $from_base);
die "Need exactly one of -t or -f" unless $to_base xor $from_base;
my $BASE = 35;
my %digits;
$digits {$_} = $_ for 0 .. 9;
foreach my $n (10 .. $BASE - 1) {
my $ch = chr (65 + $n - 10);
$digits {$ch} = $n;
$digits {$n} = $ch;
}
sub to_base ($number) {
my $out = "";
while ($number) {
$out = $digits {$number % $BASE} . $out;
$number = int ($number / $BASE);
}
$out || "0";
}
sub from_base ($number) {
my $out = 0;
while (length $number) {
my $digit = substr $number, 0, 1, "";
$out *= $BASE;
$out += $digits {$digit};
}
$out;
}
while (my $number = <>) {
chomp $number;
say $to_base ? to_base $number : from_base $number
}
__END__
Python
import fileinput
import sys
import getopt
BASE = 35
#
# Parse options
#
do_to_base = 0
do_from_base = 0
opts, args = getopt . getopt (sys . argv [1:], 'ft')
for opt, val in opts:
if opt == "-f":
do_from_base = 1
elif opt == "-t":
do_to_base = 1
if do_to_base + do_from_base != 1:
print ("Need exactly one of -f or -t")
sys . exit (1)
def to_base (number):
out = ""
while number > 0:
rest = number % BASE
if rest < 10:
char = str (rest)
else:
char = chr (65 + rest - 10)
out = char + out
number = int (number / BASE)
return out
def from_base (number):
return int (number . strip (), BASE)
#
# Need to clean argv, else fileinput will try to open a file
#
sys . argv [1:] = []
for line in fileinput . input ():
print (from_base (line) if do_from_base else to_base (int (line)))
R語言
from_base <- FALSE
to_base <- FALSE
args <- commandArgs ()
for (i in 1 : length (args)) {
if (args [i] == "-f") {
from_base <- TRUE
}
if (args [i] == "-t") {
to_base <- TRUE
}
}
to_base_35 <- function (num) {
glyphs <- c (0 : 9, LETTERS)
out <- c ()
while (num > 0) {
rem <- num %% 35
num <- num %/% 35
out <- c (glyphs [rem + 1], out)
}
paste0 (out, collapse = "")
}
stdin <- file ('stdin', 'r')
repeat {
line <- readLines (stdin, n = 1)
if (length (line) == 0) {
break
}
if (from_base) {
cat (strtoi (line, 35), "\n")
}
if (to_base) {
cat (to_base_35 (as.numeric (line)), "\n")
}
}
Ruby
require 'optparse'
BASE = 35
params = ARGV . getopts ('ft')
do_from_base = params ["f"] ? 1 : 0
do_to_base = params ["t"] ? 1 : 0
if do_from_base + do_to_base != 1
STDERR . puts "Program requires exactly one of '-f' or '-t'"
exit 1
end
def to_base (number)
out = ""
while number > 0 do
rest = number % BASE
if rest < 10
then char = rest . to_s
else char = (65 + rest - 10) . chr
end
out = char + out
number = (number / BASE) . to_i
end
return out
end
def from_base (number)
return number . to_i (35)
end
ARGF . each_line do |_|
if do_from_base == 1
then puts from_base (_)
else puts to_base (_ . to_i)
end
end