LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-20-2014, 08:54 PM   #16
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660

Quote:
Originally Posted by grail View Post
... see if you use your solution for Pascal's Triangle instead
Creating a cosmetically appealing display of Pascal's Triangle is difficult. I resorted to using a "pseudo-hexadecimal" numbering system such that a=10, ..., f=15, g=16, ..., z=35. This permits values up to 35 to be expressed as a single character.

This code ...
Code:
# Formula for calculating any element in Pascal's Triangle:
#
#          rownum!            where rownum is the number of the row ...
#  -----------------------     and elnum is the element number in that row
#   elnum!(rownum-elnum)!
#
nrows=8   # nrows = number of rows in the output file.
awk -v nrows=$nrows 'BEGIN{F[0]=1
  alphabet="123456789abcdefghijklmnopqrstuvwxyz"
  blankline="                "
  for (rownum=1;rownum<=nrows;rownum++)   # Build a table of 
    {F[rownum]=rownum*F[(rownum-1)]}      #  factorials in array F
  for (rownum=0;rownum<nrows;rownum++)    # Execute formula
    {outline=substr(blankline,1,nrows-rownum)
     for (elnum=0;elnum<=rownum;elnum++)
       outline=outline" "  \
         substr(alphabet,F[rownum]/(F[elnum]*F[rownum-elnum]),1)
   print outline}}' >$OutFile
... produced this result ...
Code:
         1
        1 1
       1 2 1
      1 3 3 1
     1 4 6 4 1
    1 5 a a 5 1
   1 6 f k f 6 1
  1 7 l z z l 7 1
Daniel B. Martin
 
Old 11-21-2014, 12:57 AM   #17
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Agreed Daniel that formatting is a little crappy

However, ignoring our formatting issue, here is the same but with bash (your factorial mileage will of course depend on your computer )
Code:
#!/usr/bin/env bash

factorial()
{
  local l_start_num

  l_start_num=$1

  if (( l_start_num == 1 || l_start_num == 0 ))
  then
    echo 1
  else
    echo $(( l_start_num * $(factorial $((--l_start_num))) ))
  fi
}

n=$1

printf "%$((n + 1))d\n" 1

for ((i = 1; i <= n; i++))
do
  for ((j = 0; j <= i; j++))
  do
    (( num = $(factorial $i) / ($(factorial $j) * $(factorial $((i - j)))) ))
    (( wspace = (j == 0)?(n - i + 1):$((${#num} + 1)) ))

    printf "%${wspace}d" $num
  done
  echo
done
 
Old 11-21-2014, 08:29 AM   #18
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by grail View Post
Agreed Daniel that formatting is a little crappy
I improved my awk solution to eliminate the use of "pseudohexidecimal" number representation.
The output formatting was improved (but not perfected) by left-padding the individual values with blanks.
This awk ...
Code:
# Formula for calculating any element in Pascal's Triangle:
#
#          rownum!            where rownum is the number of the row ...
#  -----------------------     and elnum is the element number in that row
#   elnum!(rownum-elnum)!
#
nrows=16   # nrows = number of rows in the output file.
awk -v nrows=$nrows 'BEGIN{F[0]=1
  blankline="                                        "
  for (rownum=1;rownum<=nrows;rownum++)   # Build a table of 
    {F[rownum]=rownum*F[(rownum-1)]}      #  factorials in array F
  for (rownum=0;rownum<nrows;rownum++)    # Execute formula
    {outline=substr(blankline,1,2*(nrows-rownum-1))
     for (elnum=0;elnum<=rownum;elnum++)
       {value=F[rownum]/(F[elnum]*F[rownum-elnum])
       value=substr(blankline,1,5-length(value)) value   # Pad with blanks
     outline=outline value}
   print outline}}' >$OutFile
... produced this result ...
Code:
                                   1
                                1    1
                              1    2    1
                            1    3    3    1
                          1    4    6    4    1
                        1    5   10   10    5    1
                      1    6   15   20   15    6    1
                    1    7   21   35   35   21    7    1
                  1    8   28   56   70   56   28    8    1
                1    9   36   84  126  126   84   36    9    1
              1   10   45  120  210  252  210  120   45   10    1
            1   11   55  165  330  462  462  330  165   55   11    1
          1   12   66  220  495  792  924  792  495  220   66   12    1
        1   13   78  286  715 1287 1716 1716 1287  715  286   78   13    1
      1   14   91  364 1001 2002 3003 3432 3003 2002 1001  364   91   14    1
    1   15  105  455 1365 3003 5005 6435 6435 5005 3003 1365  455  105   15    1
The awk program runs noticeably faster than the bash. The bash version recalculates the same factorials over and over again, and does that computation with a recursive routine. The awk version makes a table of factorials and then uses it multiple times.

Daniel B. Martin
 
Old 11-21-2014, 10:43 AM   #19
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,005

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Well the same pre-storage in bash does indeed increase the speed:
Code:
#!/usr/bin/env bash

n=$1
F=( 1 )

for (( i = 1; i <= n ; i++ ))
do
  F+=( $(( ${F[i-1]} * i )) )
done

for (( k = 0; k <= n; k++))
do
  for (( j = 0; j <= k; j++ ))
  do
    (( out = ${F[k]} / ( ${F[j]} * ${F[k-j]} ) ))
    (( wspace = 2 * ((j == 0)?(n - k + 1):(${#out} + ((${#out} == 1)?1:0))) ))

    printf "%${wspace}d" $out
  done
  echo
done
I improved the formatting a little but it still gets messy
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
create small linux box for environment monitoring? vbsaltydog Linux - Hardware 7 03-15-2009 11:36 AM
Best way to create a small wireless network. Master Fox General 2 10-27-2008 06:55 PM
URGENT: how to create a small LAN karthikg356 Linux - Networking 2 12-26-2007 11:43 PM
Looking for SMALL program to create graphs Mike Davies Linux - Software 7 07-01-2007 06:49 AM
How to create astlinux-like small distro? Newbie question garby Linux From Scratch 3 01-01-2007 03:33 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:00 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration