 here is a simple nick notification system for xchat using ubuntu notification system. it will execute notify-osd comment when someone mention your nick in public channel or private message. it's good for those who like to minimize their xchat while doing something :)

``````on PRIVMSG mynick {
if { [string match -nocase "*[me]*" \$_rest] } {
set thatcontext [getcontext]
set thiscontext [findcontext]
if { ![string equal \$thiscontext \$thatcontext]} {
splitsrc
if { ![regexp {listOf|nickYou|wantTo|execludeHere} \$_nick] } {
exec notify-send -i xchat -t 3000 "\$_nick/[channel \$thatcontext]" "\$_rest"
complete EAT_XCHAT
}
}
}
complete
}`````` this week i sharpen my ruby saw with an excessive about straddling checkerboard encryption.

In cryptography, a straddling checkerboard is a device for converting an alphabetic  plaintext  into digits whilst simultaneously achieving fractionation (a simple form of information diffusion) and homophony (a simple method for suppressing peaks of the frequency distribution). It also is known as a monome-dinome cipher. — wikipedia

after do some reading on how the operation was, i've workout the algorithm.

as i want to learn more about ruby but don't know what i can do with it, so i decided to write this in ruby

here's the solution

``````class Straddling
def initialize( key_text, n1, n2, n3 )
key_text = key_text+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key_text = key_text.upcase.split(//).uniq
@key_text = key_text
@n1 = n1;@n2 = n2;@n3 = n3
end

def create
@board = Array.new()
k = 0;prev = ""
for a in 0..40 do
if (a == @n1 || a == @n2 || a == @n3)
@board[a] = "_"
else
if ("A".."J") === prev

@board[a] = prev == "J"? 0:((prev)-16).chr
else
@board[a] = @key_text[k] == " " ? "*" : @key_text[k]
k+=1
end
prev = @board[a]
end
end
return @board.to_s
end

def tp(key,text)
@key = key.split(//)
@text = text.gsub(' ','*').upcase.split(//)
end

def keygen
@keygen = Array.new
@checker_board = @board.to_s.split(//)
for a in 0..@text.length-1 do
found = @checker_board.index(@text[a])
if (0..9) === found
@keygen.push(found)
elsif (10..19) === found
@keygen.push(@n1,found%10)
elsif (20..29) === found
@keygen.push(@n2,found%10)
else
@keygen.push(@n3,found%10)
end
end
end

def e(key,text)
self.tp(key,text)
self.keygen
print "#{@keygen.to_s}\n"
t = Array.new
@keygen.each do |value|
t.push((@key.to_i+value.to_i)%10)
@key << @key.shift
end
print "#{@t.to_s}\n"
print "Encrypt=#{self.show(t)}\n"
end

def d(key,text)
self.tp(key,text)
self.keygen
t = Array.new
@keygen.each do |value|
t.push((value+10-(@key).to_i)%10)
@key << @key.shift
end
print "Decrypt=#{self.show(t).gsub('*',' ')}\n"
end

def show(t)
a = 0
result = ""
while a < t.length
unless t[a] == @n1 || t[a] == @n2 || t[a] == @n3
result = result + @checker_board[t[a]]
a+=1
else
result = result + @checker_board[   t[a+1] == nil ? t[a] :  (t[a] == @n1 ? 1 : t[a] == @n2? 2:3)*10+t[a+1]         ]
a+=2
end
end
return result
end

end
puts(board.create)
board.e("2641","programming praxis")
board.d("2641","S811R53S87A18RUAS8PSSH5")
puts("\n")
board.e("2641","encrypt this text")
board.d("2641","A118R1H81A8RALR8H5ALRA180_")
puts("\n\n")
puts(board.create)
board.e("241","ruby programming rocks")
board.d("241","SF5E5*5MIREESEACY45YIS5****MESE")``````

code preview

fix: bug where it didn't check for null value after last digit

note that this code use 3 space but of course you can modify it and chose different space if you like they can fight back

25 January 2010

remember,

not matter what you do.

whatever situation you are in.

no matter how difficult it is.

do it with brain, not foot nor fist.

prevent violence at all cost as ... they can fight back too

and you don't want that! this is one of programmingpraxis exercise. written it in ruby because i need to sharpen my ruby skill :p

the question is quite easy actually. there's a lot more exciting and challenging excessive at programmingpraxis i will try during my free time. imo, this can be some kind of new hobby

``````def julian (year, month, day)
a = (14-month)/12
y = year+4800-a
m = (12*a)-3+month
return day + (153*m+2)/5 + (365*y) + y/4 - y/100 + y/400 - 32045
end
def phase (year,month,day)
p=(julian(year,month,day)-julian(2000,1,6))%29.530588853
if p<1.84566: return "New"
elsif p<5.53699: return "Waxing crescent"
elsif p<9.22831: return "First quarter"
elsif p<12.91963: return "Waxing gibbous"
elsif p<16.61096: return "Full"
elsif p<20.30228: return "Waning gibbous"
elsif p<23.99361: return "Last quarter"
elsif p<27.68493: return "Waning crescent"
else return "New"
end
end

print "#{phase(2020,1,23)}\n"
print "#{phase(1999,1,6)}\n"
print "#{phase(2010,2,10)}\n"
print "#{phase(1987,5,10)}\n"``````

preview moon phase output there is several ways we can generate a spiral number like this.

5x6 spiral

``````1  2  3  4  5  6
18 19 20 21 22  7
17 28 29 30 23  8
16 27 26 25 24  9
15 14 13 12 11 10``````

today i would like to show two ways of doing it

first, we can use mapping technique. it is done by going through the number spiral direction and map its coordinate in form of two dimensional arrays. this is pretty much easier to understand but take up a lot of resources and execution time.

here is the my mapping code (written in c++)

jump in to read more .. ;)

``````#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;

int i=0,x,y,spiral;
char direction = 'r';
void change_direction() {
switch(direction) {
case 'r':direction='d';break;
case 'd':direction='l';break;
case 'l':direction='u';break;
case 'u':direction='r';break;
}
}
int check_cell(int a,int b) {
if (b >= y || b <0) { return 0; }
else if (a >= x) { return 0; }
else if (spiral[a][b] != 0) { return 0; }
else { return 1; }
}
void move_cell(int &a,int &b) {
int next_a = a, next_b = b;
if (i == x*y-1) { return; }
switch(direction) {
case 'r': next_b = b + 1;break;
case 'd': next_a = a + 1;break;
case 'l': next_b = b - 1;break;
case 'u': next_a = a - 1;break;
}
if (check_cell(next_a,next_b)) {
a = next_a;b = next_b;
}
else {
change_direction();
move_cell(a,b);
}
return;
}

int main() {
int j,a=0,b=0;
srand((unsigned)time(0));
while (!x||!y) { x = rand()%10; y = rand()%10; }
printf("%dx%d spiral number\n",x,y);
for (i = 0;i<x*y;i++) {
spiral[a][b]=i+1;
move_cell(a,b);
}
for (i = 0;i < x;i++) {
for (j = 0;j < y;j++) {
printf("%d\t",spiral[i][j]);
}
printf("\n");
}
return 0;
}``````

preview output

in this method, all we have to do is go through the number spiral and change direction when it reach certain limit or if next cell already being occupied. it is more like a snake movement.

now, the second technique is by represent those number in matrix form. we going to create a function that going to give us a number for (i,j) position with current size of spiral (a*b) loop.

for example 5x6 spiral will be

→→→→→  j →→→→→

``````|  29 28 27 26 25 24
↓  12             23      11 10  9  8
i  13             22 -->  2         7  --> 1 0
↓  14             21      3  4   5  6      a=1 b=2
↓  15 16 17 18 19 20      a = 3 b = 4
a = 5 b = 6``````

notice that when the number from left to right then top to bottom, the number reduce from

total-[a*b-i+j+1] // note we +1 because our point start from (0,0)

meanwhile for left-side, start with (1,1) top to bottom then left to right,the number sequence are in

total-[(a-1)*(b-1)-((a-i)+(b-j))+2;]

where total is dimension of a*b. we can use recursive to loop for outer layer of spiral to inner.

here is another example. since the number is inverted, we need to minus it with total (a*b) when printing it.

``````#include <stdio.h>
#include <time.h>
int s(int i, int j, int a,int b){
return (i == 0 || j == (b-1)) ? \
(a*b) - (1 + i + j) : (i == (a-1) || j == 0) ?\
(a-1)*(b-1)-((a-i)+(b-j))+2 :\
(a > 2 || b > 2) ? s(i-1, j-1, a-2,b-2) : 0;\
}
int main() {
int x,y,a,b;
//srand((unsigned)time(0));
//while (!a||!b) { a = rand()%10; b = rand()%10; }
a = 5;b=6;
for (x=0;x < a;x++){
for (y=0;y<b;y++) printf("%d\t",a*b-s(x,y,a,b));
printf("\n\n");
}
return 0;
}``````

preview code

you can print the spiral number from inner to outer by changing a*b-s(x,y,a,b) to s(x,y,a,b) in printf ;)

i know this might not be the most optimal solution but hope i can share something with you guys

thank you :)