aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-067/jeongoon/go/ch-1.go136
-rw-r--r--challenge-086/jeongoon/common-lisp/ch-1.lsp48
-rw-r--r--challenge-086/jeongoon/go/ch-1.go55
-rw-r--r--challenge-086/jeongoon/perl/ch-2.pl26
-rw-r--r--challenge-087/jeongoon/blog.txt1
-rw-r--r--challenge-087/jeongoon/common-lisp/ch-1.lsp73
-rw-r--r--challenge-087/jeongoon/common-lisp/ch-2.lsp206
-rw-r--r--challenge-087/jeongoon/go/ch-1.go83
-rw-r--r--challenge-087/jeongoon/go/ch-2.go232
-rw-r--r--challenge-087/jeongoon/haskell/ch-1.hs31
-rw-r--r--challenge-087/jeongoon/perl/ch-1.pl41
-rw-r--r--challenge-087/jeongoon/perl/ch-2.pl232
-rw-r--r--challenge-087/jeongoon/raku/ch-1.raku22
-rw-r--r--challenge-087/jeongoon/raku/ch-2.raku115
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