aboutsummaryrefslogtreecommitdiff
path: root/challenge-123
diff options
context:
space:
mode:
author冯昶 <seaker@qq.com>2021-11-01 15:35:34 +0800
committer冯昶 <seaker@qq.com>2021-11-01 15:35:34 +0800
commit47c592ce79003fa05dc7f2d5d1f22c5ef2ff1b4e (patch)
treee17cb3ca27261d8e37f610cd90a8081a2110e6ff /challenge-123
parent6feeaa5f2efa5e3a0e27aa9610f0f686ea7c34a8 (diff)
parentaa267843f108e0b591cbbf2f13428354c74b2f70 (diff)
downloadperlweeklychallenge-club-47c592ce79003fa05dc7f2d5d1f22c5ef2ff1b4e.tar.gz
perlweeklychallenge-club-47c592ce79003fa05dc7f2d5d1f22c5ef2ff1b4e.tar.bz2
perlweeklychallenge-club-47c592ce79003fa05dc7f2d5d1f22c5ef2ff1b4e.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'challenge-123')
-rw-r--r--challenge-123/paulo-custodio/Makefile2
-rw-r--r--challenge-123/paulo-custodio/awk/ch-1.awk74
-rw-r--r--challenge-123/paulo-custodio/basic/ch-1.bas159
-rw-r--r--challenge-123/paulo-custodio/bc/ch-1.bc64
-rw-r--r--challenge-123/paulo-custodio/c/ch-1.c103
-rw-r--r--challenge-123/paulo-custodio/cpp/ch-1.cpp60
-rw-r--r--challenge-123/paulo-custodio/forth/ch-1.fs99
-rw-r--r--challenge-123/paulo-custodio/lua/ch-1.lua45
-rw-r--r--challenge-123/paulo-custodio/perl/ch-1.pl46
-rw-r--r--challenge-123/paulo-custodio/perl/ch-2.pl67
-rw-r--r--challenge-123/paulo-custodio/python/ch-1.py45
-rw-r--r--challenge-123/paulo-custodio/python/ch-2.py60
-rw-r--r--challenge-123/paulo-custodio/t/test-1.yaml25
-rw-r--r--challenge-123/paulo-custodio/t/test-2.yaml10
14 files changed, 859 insertions, 0 deletions
diff --git a/challenge-123/paulo-custodio/Makefile b/challenge-123/paulo-custodio/Makefile
new file mode 100644
index 0000000000..6316089eb8
--- /dev/null
+++ b/challenge-123/paulo-custodio/Makefile
@@ -0,0 +1,2 @@
+all:
+ perl ../../challenge-001/paulo-custodio/test.pl
diff --git a/challenge-123/paulo-custodio/awk/ch-1.awk b/challenge-123/paulo-custodio/awk/ch-1.awk
new file mode 100644
index 0000000000..78dffcaa09
--- /dev/null
+++ b/challenge-123/paulo-custodio/awk/ch-1.awk
@@ -0,0 +1,74 @@
+#!/usr/bin/gawk
+
+# TASK #1 > Ugly Numbers
+# Submitted by: Mohammad S Anwar
+# You are given an integer $n >= 1.
+#
+# Write a script to find the $nth element of Ugly Numbers.
+#
+# Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+# the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+#
+# Example
+# Input: $n = 7
+# Output: 8
+#
+# Input: $n = 10
+# Output: 12
+
+function min(a, b) {
+ return (a<b) ? a : b;
+}
+
+function min3(a, b, c) {
+ return min(a, min(b, c));
+}
+
+function alen(a, i, k) {
+ k = 0;
+ for(i in a) k++;
+ return k;
+}
+
+function push(a, v, n) {
+ n = alen(a);
+ while (n in a) n++;
+ a[n] = v;
+}
+
+function shift(a, i, v) {
+ v = a[0];
+ for (i=1; i<alen(a); i++)
+ a[i-1] = a[i];
+ delete a[alen(a)-1];
+ return v;
+}
+
+function hamming( n) {
+ # get the smallest of the multiples
+ n = min3(seq2[0], seq3[0], seq5[0]);
+
+ # shift used multiples
+ if (seq2[0] == n) shift(seq2);
+ if (seq3[0] == n) shift(seq3);
+ if (seq5[0] == n) shift(seq5);
+
+ # push next multiple
+ push(seq2, n*2);
+ push(seq3, n*3);
+ push(seq5, n*5);
+
+ return n;
+}
+
+BEGIN {
+ # sequences of hamming numbers 2*n, 3*n, 5*n
+ seq2[0] = 1;
+ seq3[0] = 1;
+ seq5[0] = 1;
+
+ n = ARGV[1] ? ARGV[1] : 5;
+ for (i=0; i<n; i++)
+ print hamming();
+ exit 0;
+}
diff --git a/challenge-123/paulo-custodio/basic/ch-1.bas b/challenge-123/paulo-custodio/basic/ch-1.bas
new file mode 100644
index 0000000000..fbd74db6fa
--- /dev/null
+++ b/challenge-123/paulo-custodio/basic/ch-1.bas
@@ -0,0 +1,159 @@
+' Challenge 003
+'
+' TASK #1 > Ugly Numbers
+' Submitted by: Mohammad S Anwar
+' You are given an integer $n >= 1.
+'
+' Write a script to find the $nth element of Ugly Numbers.
+'
+' Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+' the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+'
+' Example
+' Input: $n = 7
+' Output: 8
+'
+' Input: $n = 10
+' Output: 12
+
+' deque of integers
+type ElemType
+ nValue as integer
+ pNext as ElemType ptr
+end type
+
+type QType
+ pFront as ElemType ptr
+ pBack as ElemType ptr
+end type
+
+function QEmpty(byref q as QType) as boolean
+ if q.pFront = 0 then
+ QEmpty = true
+ else
+ QEmpty = false
+ end if
+end function
+
+function QFront(byref q as QType) as integer
+ QFront = q.pFront->nValue
+end function
+
+function QBack(byref q as QType) as integer
+ QBack = q.pBack->nValue
+end function
+
+sub QPushBack(byref q as QType, nValue as integer)
+ dim pElem as ElemType ptr
+
+ pElem = callocate(1, sizeof(ElemType))
+ pElem->nValue = nValue
+
+ if q.pFront = 0 then
+ q.pFront = pElem
+ q.pBack = pElem
+ else
+ q.pBack->pNext = pElem
+ q.pBack = pElem
+ end if
+end sub
+
+sub QPopBack(byref q as QType)
+ dim pElem as ElemType ptr
+
+ if q.pFront = 0 then ' empty
+ elseif q.pFront = q.pBack then ' only one element
+ deallocate q.pFront
+ q.pFront = 0
+ q.pBack = 0
+ else ' more than one element
+ pElem = q.pFront
+ do while pElem->pNext <> q.pBack
+ pElem = pElem->pNext
+ loop
+ deallocate q.pBack
+ q.pBack = pElem
+ pElem->pNext = 0
+ end if
+end sub
+
+sub QPushFront(byref q as QType, nValue as integer)
+ dim pElem as ElemType ptr
+
+ pElem = callocate(1, sizeof(ElemType))
+ pElem->nValue = nValue
+
+ if q.pFront = 0 then
+ q.pFront = pElem
+ q.pBack = pElem
+ else
+ pElem->pNext = q.pFront
+ q.pFront = pElem
+ end if
+end sub
+
+sub QPopFront(byref q as QType)
+ dim pElem as ElemType ptr
+
+ if q.pFront = 0 then ' empty
+ elseif q.pFront = q.pBack then ' only one element
+ deallocate q.pFront
+ q.pFront = 0
+ q.pBack = 0
+ else ' more than one element
+ pElem = q.pFront
+ q.pFront = pElem->pNext
+ deallocate pElem
+ end if
+end sub
+
+
+function min(a as integer, b as integer) as integer
+ if a < b then
+ min = a
+ else
+ min = b
+ end if
+end function
+
+function min3(a as integer, b as integer, c as integer) as integer
+ min3 = min(a, min(b, c))
+end function
+
+
+' Hamming generator
+dim shared q2 as QType
+dim shared q3 as QType
+dim shared q5 as QType
+
+function next_hamming() as integer
+ dim n as integer
+
+ ' init queues at start
+ if QEmpty(q2) then
+ QPushBack q2, 1
+ QPushBack q3, 1
+ QPushBack q5, 1
+ end if
+
+ ' get the smallest of the queue heads
+ n = min3(QFront(q2), QFront(q3), QFront(q5))
+
+ ' shift used multiples
+ if n = QFront(q2) then QPopFront q2
+ if n = QFront(q3) then QPopFront q3
+ if n = QFront(q5) then QPopFront q5
+
+ ' push next multiples
+ QPushBack q2, 2*n
+ QPushBack q3, 3*n
+ QPushBack q5, 5*n
+
+ next_hamming = n
+end function
+
+' main
+dim i as integer
+for i=1 to val(command(1))
+ print next_hamming()
+next i
diff --git a/challenge-123/paulo-custodio/bc/ch-1.bc b/challenge-123/paulo-custodio/bc/ch-1.bc
new file mode 100644
index 0000000000..3199ef0684
--- /dev/null
+++ b/challenge-123/paulo-custodio/bc/ch-1.bc
@@ -0,0 +1,64 @@
+#!/usr/bin/bc -ql
+
+/*
+TASK #1 > Ugly Numbers
+Submitted by: Mohammad S Anwar
+You are given an integer $n >= 1.
+
+Write a script to find the $nth element of Ugly Numbers.
+
+Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+
+Example
+Input: $n = 7
+Output: 8
+
+Input: $n = 10
+Output: 12
+*/
+
+scale = 0
+
+num = read()
+
+define min(a,b) {
+ if (a < b) { return a; } else { return b; }
+}
+
+define min3(a,b,c) {
+ return min(a,min(b,c));
+}
+
+q2[0] = 1; q2size = 1
+q3[0] = 1; q3size = 1
+q5[0] = 1; q5size = 1
+
+for (i = 0; i < num; i++) {
+ /* next hamming: get smallest of the queue heads */
+ h = min3(q2[0], q3[0], q5[0])
+ h
+
+ /* shift used multiples */
+ if (h == q2[0]) {
+ for (j = 1; j < q2size; j++)
+ q2[j-1] = q2[j]
+ q2size = q2size-1
+ }
+ if (h == q3[0]) {
+ for (j = 1; j < q3size; j++)
+ q3[j-1] = q3[j]
+ q3size = q3size-1
+ }
+ if (h == q5[0]) {
+ for (j = 1; j < q5size; j++)
+ q5[j-1] = q5[j]
+ q5size = q5size-1
+ }
+
+ /* push next multiples */
+ q2[q2size] = 2*h; q2size = q2size+1
+ q3[q3size] = 3*h; q3size = q3size+1
+ q5[q5size] = 5*h; q5size = q5size+1
+}
+quit
diff --git a/challenge-123/paulo-custodio/c/ch-1.c b/challenge-123/paulo-custodio/c/ch-1.c
new file mode 100644
index 0000000000..f814da939c
--- /dev/null
+++ b/challenge-123/paulo-custodio/c/ch-1.c
@@ -0,0 +1,103 @@
+/*
+TASK #1 > Ugly Numbers
+Submitted by: Mohammad S Anwar
+You are given an integer $n >= 1.
+
+Write a script to find the $nth element of Ugly Numbers.
+
+Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+
+Example
+Input: $n = 7
+Output: 8
+
+Input: $n = 10
+Output: 12
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+// implement deque
+#define Q_SIZE 100
+
+typedef struct Q {
+ size_t front;
+ size_t back;
+ int data[Q_SIZE];
+} Q;
+
+bool q_empty(Q* q) {
+ return q->front == q->back;
+}
+
+int q_front(Q* q) {
+ return q->data[q->front];
+}
+
+int q_back(Q* q) {
+ return q->data[(q->back + Q_SIZE - 1) % Q_SIZE];
+}
+
+void q_push_back(Q* q, int n) {
+ q->data[q->back] = n;
+ q->back = (q->back + 1) % Q_SIZE;
+}
+
+void q_pop_back(Q* q) {
+ q->back = (q->back + Q_SIZE -1) % Q_SIZE;
+}
+
+void q_push_front(Q* q, int n) {
+ q->front = (q->front + Q_SIZE - 1) % Q_SIZE;
+ q->data[q->front] = n;
+}
+
+void q_pop_front(Q* q) {
+ q->front = (q->front +1) % Q_SIZE;
+}
+
+int min(int a, int b) {
+ return a<b ? a : b;
+}
+
+int min3(int a, int b, int c) {
+ return min(a, min(b, c));
+}
+
+// hamming number generator
+Q q2, q3, q5;
+
+int next_hamming(void) {
+ // init three queues with 1
+ if (q_empty(&q2)) {
+ q_push_back(&q2, 1);
+ q_push_back(&q3, 1);
+ q_push_back(&q5, 1);
+ }
+
+ // get the smallest of the queue heads
+ int n = min3(q_front(&q2), q_front(&q3), q_front(&q5));
+
+ // shift used multiples
+ if (n == q_front(&q2)) q_pop_front(&q2);
+ if (n == q_front(&q3)) q_pop_front(&q3);
+ if (n == q_front(&q5)) q_pop_front(&q5);
+
+ // push next multiples
+ q_push_back(&q2, 2*n);
+ q_push_back(&q3, 3*n);
+ q_push_back(&q5, 5*n);
+
+ return n;
+}
+
+int main(int argc, char* argv[]) {
+ if (argc == 2) {
+ for (int i = 0; i < atoi(argv[1]); i++)
+ printf("%d\n", next_hamming());
+ }
+}
diff --git a/challenge-123/paulo-custodio/cpp/ch-1.cpp b/challenge-123/paulo-custodio/cpp/ch-1.cpp
new file mode 100644
index 0000000000..402443af57
--- /dev/null
+++ b/challenge-123/paulo-custodio/cpp/ch-1.cpp
@@ -0,0 +1,60 @@
+/*
+TASK #1 > Ugly Numbers
+Submitted by: Mohammad S Anwar
+You are given an integer $n >= 1.
+
+Write a script to find the $nth element of Ugly Numbers.
+
+Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+
+Example
+Input: $n = 7
+Output: 8
+
+Input: $n = 10
+Output: 12
+*/
+
+#include <iostream>
+#include <deque>
+#include <string>
+#include <algorithm>
+
+int min3(int a, int b, int c) {
+ return std::min(a, std::min(b, c));
+}
+
+// hamming number generator
+std::deque<int> q2, q3, q5;
+
+int next_hamming() {
+ // init three queues with 1
+ if (q2.empty()) {
+ q2.push_back(1);
+ q3.push_back(1);
+ q5.push_back(1);
+ }
+
+ // get the smallest of the queue heads
+ int n = min3(q2.front(), q3.front(), q5.front());
+
+ // shift used multiples
+ if (n == q2.front()) q2.pop_front();
+ if (n == q3.front()) q3.pop_front();
+ if (n == q5.front()) q5.pop_front();
+
+ // push next multiples
+ q2.push_back(2*n);
+ q3.push_back(3*n);
+ q5.push_back(5*n);
+
+ return n;
+}
+
+int main(int argc, char* argv[]) {
+ if (argc == 2) {
+ for (int i = 0; i < atoi(argv[1]); i++)
+ std::cout << next_hamming() << std::endl;
+ }
+}
diff --git a/challenge-123/paulo-custodio/forth/ch-1.fs b/challenge-123/paulo-custodio/forth/ch-1.fs
new file mode 100644
index 0000000000..b18ed9e892
--- /dev/null
+++ b/challenge-123/paulo-custodio/forth/ch-1.fs
@@ -0,0 +1,99 @@
+#! /usr/bin/env gforth
+
+\ TASK #1 > Ugly Numbers
+\ Submitted by: Mohammad S Anwar
+\ You are given an integer $n >= 1.
+\
+\ Write a script to find the $nth element of Ugly Numbers.
+\
+\ Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+\ the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+\
+\ Example
+\ Input: $n = 7
+\ Output: 8
+\
+\ Input: $n = 10
+\ Output: 12
+
+\ circular queue of integers
+1024 CONSTANT Q_SIZE \ must be power of 2
+
+: q.pFront ( q -- front-addr ) ;
+: q.pBack ( q -- back-addr ) 1 CELLS + ;
+: q.pData ( q -- data-addr ) 2 CELLS + ;
+: e.empty ( q -- f ) DUP q.pFront @ Q_SIZE MOD
+ SWAP q.pBack @ Q_SIZE MOD = ;
+: q.pElem ( q index - addr ) Q_SIZE MOD CELLS SWAP q.pData + ;
+
+: create_q ( -- )
+ CREATE 0 , 0 , Q_SIZE ALLOT \ front back data...data
+;
+
+: q.Front ( q -- front-elem )
+ DUP q.pFront @ ( q index )
+ q.pElem @
+;
+
+: q.Back ( q -- back-elem )
+ DUP q.pBack @ 1- ( q index )
+ q.pElem @
+;
+
+: q.PushBack ( q elem -- )
+ OVER q.pBack @ ( q elem back )
+ 2 PICK SWAP ( q elem q back )
+ q.pElem ( q elem elem-addr )
+ ! ( q )
+ q.pBack 1 SWAP +! \ increment
+;
+
+: q.PopBack ( q -- )
+ q.pBack -1 SWAP +!
+;
+
+: q.PushFront ( q elem -- )
+ OVER q.pFront -1 SWAP +! \ decrement front
+ SWAP dup q.pFront @ q.pElem !
+;
+
+: q.PopFront ( q -- )
+ q.pFront 1 SWAP +!
+;
+
+
+\ queue or powers of 2, 3 and 5
+create_q q2 q2 1 q.PushBack
+create_q q3 q3 1 q.PushBack
+create_q q5 q5 1 q.PushBack
+
+
+\ generate the next hamming number
+: next_hamming ( -- n )
+ \ get the smallest of the queue heads
+ q2 q.Front q3 q.Front MIN q5 q.Front MIN ( n )
+
+ \ shift used multiples
+ q2 q.Front OVER = IF q2 q.PopFront THEN
+ q3 q.Front OVER = IF q3 q.PopFront THEN
+ q5 q.Front OVER = IF q5 q.PopFront THEN
+
+ \ push next multiples
+ 2 OVER * q2 SWAP q.PushBack
+ 3 OVER * q3 SWAP q.PushBack
+ 5 OVER * q5 SWAP q.PushBack
+;
+
+
+\ generate sequence of hamming numbers
+: hamming ( n -- )
+ 0 ?DO
+ next_hamming . CR
+ LOOP
+;
+
+
+\ get command line argument, call hamming
+NEXT-ARG S>NUMBER? 0= THROW DROP
+hamming
+BYE
diff --git a/challenge-123/paulo-custodio/lua/ch-1.lua b/challenge-123/paulo-custodio/lua/ch-1.lua
new file mode 100644
index 0000000000..b491dbf71a
--- /dev/null
+++ b/challenge-123/paulo-custodio/lua/ch-1.lua
@@ -0,0 +1,45 @@
+#!/usr/bin/env lua
+
+--[[
+TASK #1 > Ugly Numbers
+Submitted by: Mohammad S Anwar
+You are given an integer $n >= 1.
+
+Write a script to find the $nth element of Ugly Numbers.
+
+Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+
+Example
+Input: $n = 7
+Output: 8
+
+Input: $n = 10
+Output: 12
+--]]
+
+-- sequence is a merge of all multiples of 2, 3 and 5
+seq2 = {1}
+seq3 = {1}
+seq5 = {1}
+
+function next_hamming()
+ -- get the smallest of the queue heads
+ local n = math.min(seq2[1], seq3[1], seq5[1])
+
+ -- shift used multiples
+ if n == seq2[1] then table.remove(seq2, 1); end
+ if n == seq3[1] then table.remove(seq3, 1); end
+ if n == seq5[1] then table.remove(seq5, 1); end
+
+ -- push next multiples
+ table.insert(seq2, 2*n)
+ table.insert(seq3, 3*n)
+ table.insert(seq5, 5*n)
+
+ return n
+end
+
+for i=1,tonumber(arg[1]) do
+ io.write(next_hamming(), "\n")
+end
diff --git a/challenge-123/paulo-custodio/perl/ch-1.pl b/challenge-123/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..3e4dd62d68
--- /dev/null
+++ b/challenge-123/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+
+# TASK #1 > Ugly Numbers
+# Submitted by: Mohammad S Anwar
+# You are given an integer $n >= 1.
+#
+# Write a script to find the $nth element of Ugly Numbers.
+#
+# Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+# the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+#
+# Example
+# Input: $n = 7
+# Output: 8
+#
+# Input: $n = 10
+# Output: 12
+
+use Modern::Perl;
+use List::Util 'min';
+
+# return an iterator to generate the sequence
+# the sequence is a merge of all multiples of 2, 3 and 5
+sub hamming_gen {
+ # sequences of hamming numbers 2*n, 3*n, 5*n
+ my @seq = ([1], [1], [1]);
+ my @base = (2, 3, 5);
+
+ return sub {
+ # get the smallest of the multiples
+ my $n = min($seq[0][0], $seq[1][0], $seq[2][0]);
+ for my $i (0..2) {
+ # shift used multiples
+ shift @{$seq[$i]} if $seq[$i][0] == $n;
+ # push next multiple
+ push @{$seq[$i]}, $n*$base[$i];
+ }
+ return $n;
+ }
+}
+
+my($n) = @ARGV;
+my $hamming = hamming_gen();
+for (1 .. $n) {
+ say $hamming->();
+}
diff --git a/challenge-123/paulo-custodio/perl/ch-2.pl b/challenge-123/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..d3de33c77f
--- /dev/null
+++ b/challenge-123/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,67 @@
+#!/usr/bin/env perl
+
+# TASK #2 > Square Points
+# Submitted by: Mohammad S Anwar
+# You are given coordinates of four points i.e.
+# (x1, y1), (x2, y2), (x3, y3) and (x4, y4).
+#
+# Write a script to find out if the given four points form a square.
+#
+# Example
+# Input: x1 = 10, y1 = 20
+# x2 = 20, y2 = 20
+# x3 = 20, y3 = 10
+# x4 = 10, y4 = 10
+# Output: 1 as the given coordinates form a square.
+#
+# Input: x1 = 12, y1 = 24
+# x2 = 16, y2 = 10
+# x3 = 20, y3 = 12
+# x4 = 18, y4 = 16
+# Output: 0 as the given coordinates doesn't form a square.
+
+use Modern::Perl;
+
+# point object
+{
+ package Point;
+ use Object::Tiny::RW qw( x y );
+
+ sub new {
+ my($class, $x, $y) = @_;
+ return bless {x=>$x, y=>$y}, $class;
+ }
+}
+
+# square of distance between two points
+sub dist_sq {
+ my($p, $q) = @_;
+ return ($p->x - $q->x) * ($p->x - $q->x) +
+ ($p->y - $q->y) * ($p->y - $q->y)
+}
+
+# check if four points form a square
+sub is_square {
+ my($p1, $p2, $p3, $p4) = @_;
+
+ my $d2 = dist_sq($p1, $p2);
+ my $d3 = dist_sq($p1, $p3);
+ my $d4 = dist_sq($p1, $p4);
+
+ return 0 if $d2 == 0 || $d3 == 0 || $d4 == 0;
+
+ return 1 if $d2 == $d3 && 2 * $d2 == $d4 &&
+ 2 * dist_sq($p2, $p4) == dist_sq($p2, $p3);
+ return 1 if $d3 == $d4 && 2 * $d3 == $d2 &&
+ 2 * dist_sq($p3, $p2) == dist_sq($p3, $p4);
+ return 1 if $d2 == $d4 && 2 * $d2 == $d3 &&
+ 2 * dist_sq($p2, $p3) == dist_sq($p2, $p4);
+ return 0;
+}
+
+my $p1 = Point->new(splice(@ARGV, 0, 2));
+my $p2 = Point->new(splice(@ARGV, 0, 2));
+my $p3 = Point->new(splice(@ARGV, 0, 2));
+my $p4 = Point->new(splice(@ARGV, 0, 2));
+
+say is_square($p1, $p2, $p3, $p4);
diff --git a/challenge-123/paulo-custodio/python/ch-1.py b/challenge-123/paulo-custodio/python/ch-1.py
new file mode 100644
index 0000000000..f736c76e1a
--- /dev/null
+++ b/challenge-123/paulo-custodio/python/ch-1.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+# TASK #1 > Ugly Numbers
+# Submitted by: Mohammad S Anwar
+# You are given an integer $n >= 1.
+#
+# Write a script to find the $nth element of Ugly Numbers.
+#
+# Ugly numbers are those number whose prime factors are 2, 3 or 5. For example,
+# the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.
+#
+# Example
+# Input: $n = 7
+# Output: 8
+#
+# Input: $n = 10
+# Output: 12
+
+import sys
+
+# return an iterator to generate the sequence
+# the sequence is a merge of all multiples of 2, 3 and 5
+def hamming_gen():
+ seq = [[1], [1], [1]]
+ base = [2, 3, 5]
+
+ while True:
+ # get the smallest of the multiples
+ n = min(seq[0][0], seq[1][0], seq[2][0])
+
+ for i in range(0, 3):
+ # shift used multiples
+ if seq[i][0] == n:
+ seq[i].pop(0)
+
+ # push next multiple
+ seq[i].append(n*base[i])
+
+ yield n
+
+
+# main
+iter = hamming_gen()
+for i in range(0, int(sys.argv[1])):
+ print(next(iter))
diff --git a/challenge-123/paulo-custodio/python/ch-2.py b/challenge-123/paulo-custodio/python/ch-2.py
new file mode 100644
index 0000000000..0d4ef50456
--- /dev/null
+++ b/challenge-123/paulo-custodio/python/ch-2.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+
+# TASK #2 > Square Points
+# Submitted by: Mohammad S Anwar
+# You are given coordinates of four points i.e.
+# (x1, y1), (x2, y2), (x3, y3) and (x4, y4).
+#
+# Write a script to find out if the given four points form a square.
+#
+# Example
+# Input: x1 = 10, y1 = 20
+# x2 = 20, y2 = 20
+# x3 = 20, y3 = 10
+# x4 = 10, y4 = 10
+# Output: 1 as the given coordinates form a square.
+#
+# Input: x1 = 12, y1 = 24
+# x2 = 16, y2 = 10
+# x3 = 20, y3 = 12
+# x4 = 18, y4 = 16
+# Output: 0 as the given coordinates doesn't form a square.
+
+import sys
+
+class Point():
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+# square of distance between two points
+def dist_sq(p, q):
+ return (p.x - q.x) * (p.x - q.x) + \
+ (p.y - q.y) * (p.y - q.y)
+
+# check if four points form a square
+def is_square(p1, p2, p3, p4):
+ d2 = dist_sq(p1, p2)
+ d3 = dist_sq(p1, p3)
+ d4 = dist_sq(p1, p4)
+
+ if d2 == 0 or d3 == 0 or d4 == 0:
+ return False
+ elif d2 == d3 and 2 * d2 == d4 and 2 * dist_sq(p2, p4) == dist_sq(p2, p3):
+ return True
+ elif d3 == d4 and 2 * d3 == d2 and 2 * dist_sq(p3, p2) == dist_sq(p3, p4):
+ return True
+ elif d2 == d4 and 2 * d2 == d3 and 2 * dist_sq(p2, p3) == dist_sq(p2, p4):
+ return True
+ else:
+ return False
+
+p1 = Point(int(sys.argv[1]), int(sys.argv[2]))
+p2 = Point(int(sys.argv[3]), int(sys.argv[4]))
+p3 = Point(int(sys.argv[5]), int(sys.argv[6]))
+p4 = Point(int(sys.argv[7]), int(sys.argv[8]))
+
+if is_square(p1, p2, p3, p4):
+ print(1)
+else:
+ print(0)
diff --git a/challenge-123/paulo-custodio/t/test-1.yaml b/challenge-123/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..1bef1a5dee
--- /dev/null
+++ b/challenge-123/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,25 @@
+- setup:
+ cleanup:
+ args: 20
+ input:
+ output: |
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 8
+ 9
+ 10
+ 12
+ 15
+ 16
+ 18
+ 20
+ 24
+ 25
+ 27
+ 30
+ 32
+ 36
diff --git a/challenge-123/paulo-custodio/t/test-2.yaml b/challenge-123/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..6ab926e8f5
--- /dev/null
+++ b/challenge-123/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,10 @@
+- setup:
+ cleanup:
+ args: 10 20 20 20 20 10 10 10
+ input:
+ output: 1
+- setup:
+ cleanup:
+ args: 12 24 16 10 20 12 18 16
+ input:
+ output: 0