diff options
| -rw-r--r-- | challenge-067/jeongoon/go/ch-1.go | 136 | ||||
| -rw-r--r-- | challenge-086/jeongoon/common-lisp/ch-1.lsp | 48 | ||||
| -rw-r--r-- | challenge-086/jeongoon/go/ch-1.go | 55 | ||||
| -rw-r--r-- | challenge-086/jeongoon/perl/ch-2.pl | 26 | ||||
| -rw-r--r-- | challenge-087/jeongoon/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-087/jeongoon/common-lisp/ch-1.lsp | 73 | ||||
| -rw-r--r-- | challenge-087/jeongoon/common-lisp/ch-2.lsp | 206 | ||||
| -rw-r--r-- | challenge-087/jeongoon/go/ch-1.go | 83 | ||||
| -rw-r--r-- | challenge-087/jeongoon/go/ch-2.go | 232 | ||||
| -rw-r--r-- | challenge-087/jeongoon/haskell/ch-1.hs | 31 | ||||
| -rw-r--r-- | challenge-087/jeongoon/perl/ch-1.pl | 41 | ||||
| -rw-r--r-- | challenge-087/jeongoon/perl/ch-2.pl | 232 | ||||
| -rw-r--r-- | challenge-087/jeongoon/raku/ch-1.raku | 22 | ||||
| -rw-r--r-- | challenge-087/jeongoon/raku/ch-2.raku | 115 |
14 files changed, 1301 insertions, 0 deletions
diff --git a/challenge-067/jeongoon/go/ch-1.go b/challenge-067/jeongoon/go/ch-1.go new file mode 100644 index 0000000000..f94efeee22 --- /dev/null +++ b/challenge-067/jeongoon/go/ch-1.go @@ -0,0 +1,136 @@ +package main + +import ( + "os" + "fmt" + "strconv" +) + +func usage() { + fmt.Println( "Usage: go run ch-1.go " + + "<M> <N> # select N from 1..M" ) +} + +type MaybeNat string + +func (str MaybeNat) Nat() Nat { + n, err := strconv.Atoi(string(str)) + if err == nil { + return(Nat(n)) + } else { + return(Nat(0)) + } +} + +func (str MaybeNat) isNatural() bool { + return(str.Nat() > 0) +} + +type Nat int +func (n Nat) String() string { + return fmt.Sprintf("%d", n) +} + + +// another my version of making combinations +// I thought there should be standard library. but I couldn't find yet. + +// a non-recursive combination modified for challenge +func combinationsIndex( M int, N int ) [][]int { + // M: number of selection ( 0 ... (M-1) ) + // N: number of choice + if M < N { + return [][]int{} + } + + initRoomSize := M - N + room := make([]int, N) + for i := range room { + room[i] = initRoomSize + } + num := make([]int, N) + for i := range num { + num[i] = i+1 + } +/* + pos := make([]int, N) + for i := range pos { + pos[i] = i + } +*/ + var combis [][]int + new_case := make([]int, N) + //copy(new_case, pos) + copy(new_case, num) + combis = append( [][]int{}, new_case ) + + cursor := N - 1 // initial: index of last elements in selection + + for { + if room[cursor] > 0 { + room[cursor]-- + //pos[cursor]++ + num[cursor]++ + new_case := make([]int, N) + //copy(new_case, pos) + copy(new_case, num) + combis = append( combis, new_case ) + } else { + cursor_moved := false + for i := cursor; i > 0; i-- { + if room[i-1] > 0 { + cursor = i-1 + cursor_moved = true + break + } + } + if cursor_moved { + new_room := room[cursor] - 1 + //base_pos := pos[cursor]; + base_num := num[cursor]; + for p, i := 1, cursor; i < N; i++ { + room[i] = new_room + //pos[i] = base_pos + p + num[i] = base_num + p + p++ // p++, i++ not working on for() + } + new_case := make([]int, N) + //copy(new_case, pos) + copy(new_case, num) + combis = append(combis, new_case) + cursor = N - 1 + } else { + break + } + } + + } + + return combis +} + +func main() { + if len(os.Args[1:]) != 2 { + usage(); + os.Exit(1); + } + + var N []Nat + all_good := true + + for _, str := range os.Args[1:] { + if MaybeNat(str).isNatural() { + N = append(N, MaybeNat(str).Nat()) + } else { + all_good = false + break + } + } + + if ! all_good { + usage(); + os.Exit(2); + } + + fmt.Println(combinationsIndex( int(N[0]), int(N[1]) )); +} diff --git a/challenge-086/jeongoon/common-lisp/ch-1.lsp b/challenge-086/jeongoon/common-lisp/ch-1.lsp new file mode 100644 index 0000000000..da75895816 --- /dev/null +++ b/challenge-086/jeongoon/common-lisp/ch-1.lsp @@ -0,0 +1,48 @@ +;; tested with sbcl --script 15 20 -15 0 30 + +(defun get-command-line () + (or + #+CLISP *args* + #+SBCL *posix-argv* + #+LISPWORKS system:*line-arguments-list* + #+CMU extensions:*command-line-words* + nil)) + +(defparameter *cmdline* (get-command-line)) + +(when (< (length *cmdline*) 3) (print-usage) (quit)) + +(defun print-usage () + (format t "Usage: sbcl --script ch-1.lsp <target diff(positive integer)> <integer> ...")) + +(defparameter *integer-list* (map 'list #'parse-integer (rest *cmdline*))) +(defvar target-diff (first *integer-list*)) + +(when (< target-diff 0) (print-usage) (quit)) + +(defvar int-list (rest *integer-list*)) +(sort int-list #'<) ;; sort in place + +(defvar found nil) + +;; (solution ...) +(loop for int-vec = (coerce (rest int-list) 'vector) + for left-val = (first int-list) + do(if (or found (null left-val)) + (return) + ;; else + (loop for right-val across int-vec + do(let ((df (- right-val left-val))) + (if (= df target-diff) + (progn (format t "1 as ~A - ~A = ~A~%" + right-val left-val target-diff) + (setq found t) + (return)) + (when (> df target-diff) + ;; no meaning go foward: move left value by + ;; shifting (cdr, or rest) + (setq int-list (rest int-list)) + (return)))) + finally (setq int-list (rest int-list))))) + +(when (null found) (format t "0")) diff --git a/challenge-086/jeongoon/go/ch-1.go b/challenge-086/jeongoon/go/ch-1.go new file mode 100644 index 0000000000..10e1e30d79 --- /dev/null +++ b/challenge-086/jeongoon/go/ch-1.go @@ -0,0 +1,55 @@ +// tested with go run ch-1.go 1 3 2 -1 -2 -3 6 7 9 10 + +package main + +import ( + "os" + "fmt" + "sort" + "strconv" +) + +func usage() { + fmt.Println( "Usage: go run ch-1.go <target diff(positive interger)> <integer> ..." ) +} + +func main() { + if len(os.Args[1:]) < 3 { + usage() + os.Exit(1); + } + + var ns []int + + for _, nstr := range os.Args[1:] { + n, err := strconv.Atoi(nstr) + if err == nil { + ns = append(ns, n) + } else { + fmt.Fprintln(os.Stderr, nstr, "is ignored: ", err) + } + } + + df := ns[ 0] // diff + ns = ns[1:] + sort.Ints(ns) + + found := false + + for i := 1; i < len(ns); i++ { + cdf := ns[i] - ns[0] + if cdf == df { + fmt.Printf("1 as %d - %d = %d", ns[i], ns[0], df) + found = true + break + } else if cdf > df { // no need to check further + ns = ns[1:] // reduce list size + i = 1 // and reset cursor + } + } + + if ! found { + fmt.Println("0") + } + +} diff --git a/challenge-086/jeongoon/perl/ch-2.pl b/challenge-086/jeongoon/perl/ch-2.pl index 91eff4c6ca..ea68453581 100644 --- a/challenge-086/jeongoon/perl/ch-2.pl +++ b/challenge-086/jeongoon/perl/ch-2.pl @@ -2,6 +2,9 @@ # -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- # -*- coding: utf-8 -*- +# test with: +# cat *anysudokufile* | perl ch-2.pl + use strict; use warnings; use v5.32; # syntax for a < x < b @@ -15,6 +18,23 @@ struct RowCandi => [ rowNum => '$', candidates=> '%', our $d = 0; ++$|; +sub readInputFromStdin () { + # identify only [_1-9] + my @input = (); + while (<STDIN>) { + my @line = grep { /[_1-9]/ } split /\b/; + + if ( scalar @line == 9 ) { + push @input, [ @line ]; + } + else { + warn "something I didn't understand line: $.: $_; -> ignored."; + } + last if scalar @input == 9; + } + @input +} + sub newRowCandi ($$) { my ($sketch, $rn) = @_; @@ -185,6 +205,8 @@ sub getRefWholeSnapshot ($$) { } (0..$#{$sketch}) ] } +=pod Example + my @P = ( [ qw[_ _ _ 2 6 _ 7 _ 1] ], [ qw[6 8 _ _ 7 _ _ 9 _] ], [ qw[1 9 _ _ _ 4 5 _ _] ], @@ -195,6 +217,10 @@ my @P = ( [ qw[_ _ _ 2 6 _ 7 _ 1] ], [ qw[_ 4 _ _ 5 _ _ 3 6] ], [ qw[7 _ 3 _ 1 8 _ _ _] ] ); +=cut + +my @P = readInputFromStdin(); + my $ri; my @rowCandidates = (); my @canvas = map { [ @$_ ] } @P; # copy diff --git a/challenge-087/jeongoon/blog.txt b/challenge-087/jeongoon/blog.txt new file mode 100644 index 0000000000..89d247e6a0 --- /dev/null +++ b/challenge-087/jeongoon/blog.txt @@ -0,0 +1 @@ +https://dev.to/jeongoon/weekly-challenge-086-task-1-perl-raku-2hk4 diff --git a/challenge-087/jeongoon/common-lisp/ch-1.lsp b/challenge-087/jeongoon/common-lisp/ch-1.lsp new file mode 100644 index 0000000000..13f5a9bdb3 --- /dev/null +++ b/challenge-087/jeongoon/common-lisp/ch-1.lsp @@ -0,0 +1,73 @@ +;; tested with sbcl --script ch-1.lsp 1 3 2 -1 -2 -3 6 7 9 10 +;;; (output) +;; longest consecutive sequence(s): size:3 +;; (-3 -2 -1) +;; (1 2 3) + +;;; Comment: +;; I thought (sort x #'<) is sorted in place of x +;; however, it didn't work properly until I did (setq x (sort x #'<)) + + +(defun get-command-line () + (or + #+CLISP *args* + #+SBCL *posix-argv* + #+LISPWORKS system:*line-arguments-list* + #+CMU extensions:*command-line-words* + nil)) + +(defparameter *cmdline* (get-command-line)) + +(defun print-usage () + (format t "Usage: sbcl --script ch-1.lsp <integer> ...")) + +(when (< (length *cmdline*) 3) (print-usage) (quit)) + +(defparameter *integer-list* (map 'list #'parse-integer (rest *cmdline*))) + +;; even though I tried to coerce; still sorting has problem !!! +(defvar int-list (map 'list #'(lambda (x) (coerce x 'integer)) (remove-duplicates *integer-list*))) +(setq int-list (sort int-list #'<)) ;; (setq ... is must (tested with sbcl 2.0.5)) +(format t "~A~%" int-list) + +(when (not (= (length *integer-list*) (length int-list))) + (format t "*THIS IS SBCL BUG*:~%Orignal list: ~A~%List after sorting: ~A~%" + *integer-list* int-list)) + +(defvar longest-size 0) +(defvar longest-seq-list '()) +(defvar curr-seq '()) + +(defvar last-int (first int-list)) + + +;; (solution ...) +(loop for curr-int in (append (rest int-list) + (list (+ (apply #'max int-list) 2))) + ;; note: dummy added for last checking any sequence left + + do(if (= last-int (1- curr-int)) + (if (null curr-seq) + (setq curr-seq (list last-int curr-int)) + (nconc curr-seq (list curr-int))) + ;; else + (let ((curr-size (length curr-seq))) + (if (< longest-size curr-size) + (setq longest-size curr-size + longest-seq-list (list curr-seq)) + ;; else + (when (= longest-size curr-size) + (setq longest-seq-list + (append longest-seq-list (list curr-seq))))) + (setq curr-seq '()))) + + do(setq last-int curr-int)) + +(if (< 0 longest-size ) + (progn + (format t "longest consecutive sequence(s): size:~A~%" longest-size) + (map nil #'(lambda (a-list) (format t "~A~%" a-list)) longest-seq-list)) + (format t "0 as no consecutive sequence found")) + +(quit) diff --git a/challenge-087/jeongoon/common-lisp/ch-2.lsp b/challenge-087/jeongoon/common-lisp/ch-2.lsp new file mode 100644 index 0000000000..5faeae6023 --- /dev/null +++ b/challenge-087/jeongoon/common-lisp/ch-2.lsp @@ -0,0 +1,206 @@ +;; tested with: +;; echo "[000111][111111][001001][001111][001111] | sbcl --script ch-2.lsp +;; [000111] +;; [111111] +;; [001001] +;; [001111] +;; [001111] + +(defun get-command-line () + (or + #+CLISP *args* + #+SBCL *posix-argv* + #+LISPWORKS system:*line-arguments-list* + #+CMU extensions:*command-line-words* + nil)) + +(defparameter *cmdline* (get-command-line)) +(defparameter *rows-list* '()) +(defvar row '()) + +;; read from stdin +(loop for line = (read-line *standard-input* nil) + while line + do(loop for ch in (coerce line 'list) + do(if (or (char= ch #\1) (char= ch #\0)) + (if (null row) (setq row (list ch)) (nconc row (list ch))) + (when (or (char= ch #\]) + (and (char= ch #\newline) (not (null row)))) + (if (null *rows-list*) + (setq *rows-list* (list row)) + (nconc *rows-list* (list row))) + (setq row '()))))) + + +(defparameter *num-rows* (length *rows-list*)) +(defparameter *num-columns* (length (first *rows-list*))) + +(defun ch-087/subsequences (lines) + (let ((seqs '())) + (loop for line in lines + do(loop while (not (null line)) + do(let ((points-so-far '())) + (loop for point in line + do(progn + (if (null points-so-far) + (setq points-so-far (list point)) + (nconc points-so-far (list point))) + (if (null seqs) + (setq seqs (list (copy-list + points-so-far))) + (nconc seqs (list (copy-list + points-so-far))))))) + (setq line (rest line)))) + seqs)) + +;;; +;;; check data row by row and find lines which consist of cosecutive points +;;; +(defun find-consecuative-lines (columns) ;; a point inclusive + ;; i.e. (1 1 1 0 1) -> ((0 1 2) (4)) + ;; and more ((0) (1) (2) (0 1) (1 2) + ;; (0 1 2) (4)) + (let* ((lines '()) + (curr-points '()) + (prev (first columns))) + (when (char= #\1 prev) (setq curr-points (list 0))) + (loop for curr in (rest columns) + for i from 1 + do(if (char= #\1 prev) + (if (char= #\1 curr) + (if (null curr-points) + (setq curr-points (list (1- i) i)) ;; remember position + (nconc curr-points (list i))) + ;; current line ends here: push into lines list + (progn + (if (null lines) + (setq lines (list curr-points)) + (nconc lines (list curr-points))) + (setq curr-points '()))) + ;; there is no line we looking at currently + (when (char= #\1 curr) ;; but start new one + (setq curr-points (list i))) ;; remember position + ) + do(setq prev curr)) + (when (not (null curr-points)) ;; add if loop not executed or ended without + ;; appending last line + (if (null lines) + (setq lines (list curr-points)) + (nconc lines (list curr-points)))) + (ch-087/subsequences lines))) ;; get subsequeces as well + + +(defvar lines-per-row) +(setq lines-per-row + (loop for row in *rows-list* + for ri from 0 + collect (map 'list #'(lambda (ls) (cons ri (list ls))) + (find-consecuative-lines row)))) + +;;(format t "~A~%" lines-per-row) + +(defun ch-087/intersects (cmp-list) + ;; get intersections of all member in cmp-list + ;; but with :key #'cdr :test #'equal + (if (< (length cmp-list) 1) + '() ;; empty list + ;; else + (let* ((inters (first cmp-list))) + (loop for curr in (rest cmp-list) + do(progn + (setq inters (intersection inters curr + :key #'cdr :test #'equal)) + ;;(format t "inters: ~a~%" inters) + (when (null inters) (return)))) + (map 'list #'(lambda (x) (cadr x)) inters)))) + +(defvar lines-per-row-cp (copy-list lines-per-row)) +(defvar found-rectangles '()) + +;; +;; find possible rectangles +;; +(loop for base from 0 + ;; note: checking procedure is similar to below + ;; 1 2 3 4 -> + ;; 1 -> 1 2 -> 1 2 3 -> 1 2 3 4 + ;; 2 -> 2 3 -> 2 3 4 -> + ;; 3 -> 3 4 -> + ;; 4 + while (not (null lines-per-row-cp)) + do(let ((lines-in-rows '()) + (rows-numbers '()) + (intersection-so-far '()) + (inters '())) + (loop named adding-row + for line-in-row in lines-per-row-cp + for offset from 0 + do (progn + (if (null rows-numbers) + (setq rows-numbers (list (+ base offset))) + (nconc rows-numbers (list (+ base offset)))) + (setq lines-in-rows (append lines-in-rows + (list line-in-row))) + (setq inters + (ch-087/intersects lines-in-rows)) + (if (null inters) + (return-from adding-row) ;; no need to go further + (setq intersection-so-far + ;; making a list looks like below + ;; ( ( (row numbers ...) (points ...) ) ... ) + (map + 'list #'(lambda (x) + (cons rows-numbers (list x))) + inters))))) + + ;; sometimes collect() is working unexpectedly + ;; (probably thanks to lack of my knowledge -.-;) + ;; just do(let... setq(... )) by myself + (when (not (null intersection-so-far)) + (if (null found-rectangles) + (setq found-rectangles (copy-list intersection-so-far)) + (nconc found-rectangles (copy-list intersection-so-far))))) + ;; reducing list + do (setq lines-per-row-cp (cdr lines-per-row-cp))) + +;;(format t "~A~%" found-rectangles) + +;; +;; find largest +;; +;; ( ((0 1) (1 2)) ;; (row from 0 to 1) (column from 1 to 2) +;; ((1 2 3) (4 5)) ... ) + +(defvar largest-area 0) +(defvar largest-rectangle-list '()) + +(loop for rect in found-rectangles + do (let* ((rows (car rect)) + (cols (cadr rect)) + (curr-area (* (length rows) (length cols)))) + (if (= curr-area 1) + nil ;; ignore if it is a point + (if (< largest-area curr-area) + ;; update + (progn (setq largest-area curr-area) + (setq largest-rectangle-list (list rect))) + (when (= largest-area curr-area) + ;; append + (if (null largest-rectangle-list) + (setq largest-rectangle-list (list rect)) + (nconc largest-rectangle-list (list rect)))))))) +;; +;; show the result +;; + +(if (null largest-rectangle-list) + (format t "0 as no rectangle found") + (dolist (rect largest-rectangle-list) + (let* ((rows (car rect)) + (cols (cadr rect))) + (format t "largest area: ~d~%" largest-area) + (format t "at (r:~d,c:~d)~%" (first rows) (first cols)) + (dotimes (r (length rows)) + (format t "~{~a~^ ~}~%" + (coerce (make-array + (length cols) :initial-element #\1) 'list)))))) diff --git a/challenge-087/jeongoon/go/ch-1.go b/challenge-087/jeongoon/go/ch-1.go new file mode 100644 index 0000000000..3803d7d050 --- /dev/null +++ b/challenge-087/jeongoon/go/ch-1.go @@ -0,0 +1,83 @@ +// tested with go run ch-1.go 1 3 2 -1 -2 -3 6 7 9 10 + +package main + +import ( + "os" + "fmt" + "sort" + "strconv" +) + +func usage() { + fmt.Println( "Usage: go run ch-1.go <integer> ..." ) +} + +func main() { + switch len(os.Args[1:]) { + case 0: + usage() + os.Exit(1); + case 1: + fmt.Println("0 as only one element given") + os.Exit(0); + } + + var ns []int + + for _, nstr := range os.Args[1:] { + n, err := strconv.Atoi(nstr) + if err == nil { + ns = append(ns, n) + } else { + fmt.Fprintln(os.Stderr, nstr, "is ignored: ", err) + } + } + + sort.Ints(ns) + + longest_size := 0 + longest_seq_ls := [][]int{} + cseq := []int{} + + lv := ns[0]; // last value + ns = append(ns, ns[len(ns)-1] + 2) // add dummy + + for _, v := range ns[1:] { + switch v - lv { + case 1: // add new member to current seq + if len(cseq) == 0 { + cseq = []int{lv, v} + } else { + cseq = append(cseq, v) + } + case 0: // skip + default: + clen := len(cseq) + if longest_size < clen { // new longest ! + + // update size + longest_size = clen + // new longest seq + longest_seq_ls = [][]int{ cseq } + } else if ( longest_size == clen ) { // same longest + // add to longest_seq_ls + longest_seq_ls = append(longest_seq_ls, cseq) + } + // reset current status + cseq = []int{} + } + lv = v // update last value + } + + if len(longest_seq_ls) > 0 { + fmt.Println("longest size:", longest_size) + fmt.Println("sequence(s):") + for _, sq := range longest_seq_ls { + fmt.Println(sq) + } + } else { + fmt.Println("0") + } + +} diff --git a/challenge-087/jeongoon/go/ch-2.go b/challenge-087/jeongoon/go/ch-2.go new file mode 100644 index 0000000000..f30049cafe --- /dev/null +++ b/challenge-087/jeongoon/go/ch-2.go @@ -0,0 +1,232 @@ +/* tested with: echo '[000111][111111][001001][001111][001111]' | go run ch-2.go + * `-> example 3 + * echo '[101010][010101][101010][010101]' | go run ch-2.go + * `-> example 1 + */ +package main + +import ( + "os" + "bufio" + "fmt" + "strings" + "reflect" +) + +func usage() { + fmt.Println( "Usage: echo [1101][1100][0111][1011]' | go run ch-2.go" ) +} + +// this function will ignore any other information but "0","1","]" +func getPointsFromMatrixLines (raw string) [][]int { + var rowsOut [][]int + // remove new lines separated by [] + lines := strings.Split(raw, "\n") + joined := strings.Join(lines, "") + matrixlines := strings.Split(joined, "]") + + for ln, line := range matrixlines { + x := 0 + var points []int + // collect useful data only + for _, singleStr := range line { + switch string(singleStr) { + case "1": + points = append( points, x ) + x++ + case "0": + x++ + case "[": // okay but not used + case " ": + default: + fmt.Fprintf( os.Stderr, + "Wrong character(%s) at row: %d\n", + singleStr, ln ) + + } + } + rowsOut = append( rowsOut, points ) + } + return rowsOut +} + + +type FullHLine struct { + points []int + row int +} + +func (hl FullHLine) Length() int { + return hl.points[len(hl.points)-1] - hl.points[0] +} + +func (hl FullHLine) StartingPoint() int { + return hl.points[0] +} + +type Rect struct { + rows []int + cols []int +} + +func (rect Rect) NorthWest() (int, int) { + // ref: https://gobyexample.com/multiple-return-values + return rect.rows[0], rect.cols[0] +} + +func (rect Rect) Area() int { + return len(rect.rows) * len(rect.cols) +} + +func getSubHorizLinesFromHorizLines ( hlinesARow []FullHLine ) []FullHLine { + var subHlinesAtARow []FullHLine + for _, hline := range hlinesARow { + for hl := hline ;len(hl.points) > 0; hl.points = hl.points[1:] { + var pnts_so_far []int; + for _, pnt := range(hl.points) { + pnts_so_far = append(pnts_so_far, pnt) + subHlinesAtARow = append(subHlinesAtARow, + FullHLine {pnts_so_far, hline.row} ) + } + } + } + return subHlinesAtARow +} + +func getHorizLinesFromPoints ( pointsAtRows [][]int ) [][]FullHLine{ + var hlinesAtRows [][]FullHLine + + for r, points := range pointsAtRows { + // note: a point will be allowed as a line + // so we can make a vertical line later on + // and vertical line is regarded as a rectangle + // in my implementation + if len(points) == 0 { + continue // skip empty line + } + points = append(points, points[len(points)-1] + 2) // dummy + prev := points[0] + pnts := []int{prev} + var hlinesAtARow []FullHLine + + for _, curr := range points[1:] { + if (curr - prev) == 1 { + pnts = append(pnts, curr) + } else { + if len(pnts) > 0 { + hlinesAtARow = append(hlinesAtARow, + FullHLine { pnts, r } ) + } + pnts = []int{curr} + } + prev = curr + } + + hlinesAtRows = append(hlinesAtRows, + getSubHorizLinesFromHorizLines(hlinesAtARow)) + } + + return hlinesAtRows +} + +func findLargestRectanglesFromHorizLines (hlinesAtRows [][]FullHLine) []Rect { + var largestRects []Rect + largestArea := 0 + + /* note: checking procedure is similar to below + * 1 2 3 4 -> // each number represents row number + * 1 -> 1 2 -> 1 2 3 -> 1 2 3 4 // but intersection is decreasing + * 2 -> 2 3 -> 2 3 4 -> + * 3 -> 3 4 -> + * 4 + */ + + + for + base, har := 0, hlinesAtRows; + len(har) > 0; + base, har = base+1, har[1:] { + intersects := har[0] // initial intersection is same as first row + var rows []int + candidates: + for offset, candi:= range har { + rows = append(rows, base+offset) + var inters []FullHLine + for _, hlc := range candi { + for _, hli := range intersects { + if hli.row != hlc.row && + hlc.row - hli.row > 1 { + // ignore if not consecutive + continue; + } + if reflect.DeepEqual( + hlc.points, hli.points) { + //fmt.Println( base, ":", hlc, "~~", hli ) + // keep intersection + inters = append(inters, hlc) + r_cp := rows + c_cp := hli.points + rect := Rect { r_cp,c_cp } + narea := rect.Area() + if narea == 1 { + // skip a point + continue + } + // compare with largest + // and update largest + // if needed + if largestArea < narea { + largestArea = + narea + largestRects = + []Rect{rect} + //fmt.Println( "new largest", largestRects) + } else if largestArea == + narea { + largestRects = append( + largestRects, + rect ) + //fmt.Println( "update largest", largestRects) + } + } else { + // remove from intersec. + } + } + if len(inters) == 0 { + break candidates // no need to go further + } else { + copy(intersects, inters) + } + } + } + } + return largestRects +} + +func main() { + reader := bufio.NewReader(os.Stdin) + matrixString, _ := reader.ReadString('') + pointsAtRows := getPointsFromMatrixLines(matrixString) + hlinesAtRows := getHorizLinesFromPoints(pointsAtRows) + //fmt.Println( hlinesAtRows ) + largestRects := findLargestRectanglesFromHorizLines(hlinesAtRows) + + if len(largestRects) == 0 { + fmt.Println("0 as no rectangle found") + os.Exit(1) + } else { + fmt.Fprintln(os.Stderr, "Area:", largestRects[0].Area()) + for _, rect := range largestRects { + y, x := rect.NorthWest() + fmt.Fprintf(os.Stderr, "At: (r:%d,c:%d)\n", y, x) + for range rect.rows { + fmt.Print("1") + for range rect.cols[1:] { + fmt.Print(" 1") + } + fmt.Println("") + } + } + } + os.Exit(0) +} diff --git a/challenge-087/jeongoon/haskell/ch-1.hs b/challenge-087/jeongoon/haskell/ch-1.hs new file mode 100644 index 0000000000..dc2d24e980 --- /dev/null +++ b/challenge-087/jeongoon/haskell/ch-1.hs @@ -0,0 +1,31 @@ +import System.Environment +import System.Exit +import Data.Char (isNumber) +import Data.Maybe (catMaybes) +import Data.List (sort, sortBy) + +{- tested with: runhaskell ch-1.hs 1 3 2 -1 -2 -3 6 7 9 1 +(only shows one answer) +-} + +answerLongestConsecutiveSequence :: [Int] -> [Int] +answerLongestConsecutiveSequence = + ( head + . sortBy (\a b -> (length b) `compare` (length a)) + . consecutiveSequences ) + + where + consecutiveSequences = + ( scanl1 (\a b -> if (head b)-(last a) == 1 then (a++b) else b) + . map (:[]) + . sort ) + +main = do + (catMaybes.map (\nStr -> + if (all isNumber nStr) then Just(read nStr :: Int) + else Nothing )) `fmap` getArgs + >>= (\nums -> + if length nums < 1 then + die "Usage: runhaskell ch-1.hs <integer> ..." + else + putStrLn $ show ( answerLongestConsecutiveSequence nums ) ) diff --git a/challenge-087/jeongoon/perl/ch-1.pl b/challenge-087/jeongoon/perl/ch-1.pl new file mode 100644 index 0000000000..3de5d2bc6b --- /dev/null +++ b/challenge-087/jeongoon/perl/ch-1.pl @@ -0,0 +1,41 @@ +#!/usr/bin/env perl +# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- +# -*- coding: utf-8 -*- + +use strict; use warnings; +use v5.26; + +# note: no sanity check !! +my @sorted = sort { $a <=> $b } @ARGV; +push @sorted, $sorted[-1]+2; # dummy + +my @longest_seq_list = (); +my $longest_size = 0; + +my $prev = shift @sorted; +my @curr_seq = ($prev); + +for my $curr (@sorted) { + if ( $curr - $prev == 1 ) { + push @curr_seq, ($curr); # concat. current seq + } elsif ( $curr == $prev ) { # skip + } else { # update longest + my $curr_size = scalar @curr_seq; + if ( $curr_size > $longest_size ) { + $longest_size = $curr_size; + @longest_seq_list = ( [ @curr_seq ] ); + } elsif ( $curr_size == $longest_size ) { + push @longest_seq_list, [ @curr_seq ]; + } + @curr_seq = ($curr); + } + $prev = $curr; +} + +if ( $longest_size > 0 ) { + say "longest size: ".$longest_size; + say "total ".(scalar @longest_seq_list)." sequencies found."; + for my $seq (@longest_seq_list) { + say "[", join(", ", @$seq), "]"; + } +} diff --git a/challenge-087/jeongoon/perl/ch-2.pl b/challenge-087/jeongoon/perl/ch-2.pl new file mode 100644 index 0000000000..95c6e9feec --- /dev/null +++ b/challenge-087/jeongoon/perl/ch-2.pl @@ -0,0 +1,232 @@ +#!/usr/bin/env perl +# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- +# -*- coding: utf-8 -*- + +# tested with: +# echo "[000111][111111][001001][001111][001111] | sbcl --script ch-2.lsp +# [000111] +# [111111] +# [001001] +# [001111] +# [001111] + +# modified from ch-084/ch-2.pl +use strict; use warnings; +use v5.26; + +use Class::Struct; + +struct PointInMat => [ row => '$', col => '$' ]; +struct HLineInMat => [ row => '$', begin => '$', end => '$' ]; +struct RectInMat => [ row_NW => '$', col_NW => '$', + row_SE => '$', col_SE => '$' ]; +struct RunAndShow => [ Run => '$', Show => '$' ]; +struct ShowDetails => [ name => '$', attrs => '@' ]; + +sub rectArea ($) { + my $rect = shift; + + ($rect->row_SE - $rect->row_NW + 1) + * + ($rect->col_SE - $rect->col_NW + 1) +} + +sub readContents { + local $/ = ''; # slurp + my $contents = <STDIN> // ''; + $contents +} + +# return as an ArrayRef of ArrayRef of PointInMat (grouped by row number) +sub getPointsAtEa |
