天天看點

程式設計挑戰賽第二周:題目以及各種程式設計語言解答

作者:啟辰8
程式設計挑戰賽第二周:題目以及各種程式設計語言解答

我們的目标是讓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
           

繼續閱讀