Planet Scheme

May 19, 2019

GNU Guix

GNU Guix 1.0.1 released

We are pleased to announce the release of GNU Guix version 1.0.1. This new version fixes bugs in the graphical installer for the standalone Guix System.

The release comes with ISO-9660 installation images, a virtual machine image, and with tarballs to install the package manager on top of your GNU/Linux distro, either from source or from binaries. Guix users can update by running guix pull.

It’s been just over two weeks since we announced 1.0.0—two weeks and 706 commits by 40 people already!

This is primarily a bug-fix release, specifically focusing on issues in the graphical installer for the standalone system:

  • The most embarrassing bug would lead the graphical installer to produce a configuration where %base-packages was omitted from the packages field. Consequently, the freshly installed system would not have the usual commands in $PATHls, ps, etc.—and Xfce would fail to start for that reason. See below for a “post-mortem” analysis.
  • The wpa-supplicant service would sometimes fail to start in the installation image, thereby breaking network access; this is now fixed.
  • The installer now allows you to toggle the visibility of passwords and passphrases, and it no longer restricts their length.
  • The installer can now create Btrfs file systems.
  • network-manager-applet is now part of %desktop-services, and thus readily usable not just from GNOME but also from Xfce.
  • The NEWS file has more details, but there were also minor bug fixes for guix environment, guix search, and guix refresh.

A couple of new features were reviewed in time to make it into 1.0.1:

  • guix system docker-image now produces an OS image with an “entry point”, which makes it easier to use than before.
  • guix system container has a new --network option, allowing the container to share networking access with the host.
  • 70 new packages were added and 483 packages were updated.
  • Translations were updated as usual and we are glad to announce a 20%-complete Russian translation of the manual.

Recap of bug #35541

The 1.0.1 release was primarily motivated by bug #35541, which was reported shortly after the 1.0.0 release. If you installed Guix System with the graphical installer, chances are that, because of this bug, you ended up with a system where all the usual GNU/Linux commands—ls, grep, ps, etc.—were not in $PATH. That in turn would also prevent Xfce from starting, if you chose that desktop environment for your system.

We quickly published a note in the system installation instructions explaining how to work around the issue:

  • First, install packages that provide those commands, along with the text editor of your choice (for example, emacs or vim):

    guix install coreutils findutils grep procps sed emacs vim
  • At this point, the essential commands you would expect are available. Open your configuration file with your editor of choice, for example emacs, running as root:

    sudo emacs /etc/config.scm
  • Change the packages field to add the “base packages” to the list of globally-installed packages, such that your configuration looks like this:

    (operating-system
      ;; … snip …
      (packages (append (list (specification->package "nss-certs"))
                        %base-packages))
      ;; … snip …
      )
  • Reconfigure the system so that your new configuration is in effect:

    guix pull && sudo guix system reconfigure /etc/config.scm

If you already installed 1.0.0, you can perform the steps above to get all these core commands back.

Guix is purely declarative: if you give it an operating system definition where the “base packages” are not available system-wide, then it goes ahead and installs precisely that. That’s exactly what happened with this bug: the installer generated such a configuration and passed it to guix system init as part of the installation process.

Lessons learned

Technically, this is a “trivial” bug: it’s fixed by adding one line to your operating system configuration and reconfiguring, and the fix for the installer itself is also a one-liner. Nevertheless, it’s obviously a serious bug for the impression it gives—this is not the user experience we want to offer. So how did such a serious bug go through unnoticed?

For several years now, Guix has had a number of automated system tests running in virtual machines (VMs). These tests primarily ensure that system services work as expected, but some of them specifically test system installation: installing to a RAID or encrypted device, with a separate /home, using Btrfs, etc. These tests even run on our continuous integration service (search for the “tests.*” jobs there).

Unfortunately, those installation tests target the so-called “manual” installation process, which is scriptable. They do not test the installer’s graphical user interface. Consequently, testing the user interface (UI) itself was a manual process. Our attention was, presumably, focusing more on UI aspects since—so we thought—the actual installation tests were already taken care of by the system tests. That the generated system configuration could be syntactically correct but definitely wrong from a usability viewpoint perhaps didn’t occur to us. The end result is that the issue went unnoticed.

The lesson here is that: manual testing should also look for issues in “unexpected places”, and more importantly, we need automated tests for the graphical UI. The Debian and Guix installer UIs are similar—both using the Newt toolkit. Debian tests its installer using “pre-seeds” (code), which are essentially answers to all the questions and choices the UI would present. We could adopt a similar approach, or we could test the UI itself at a lower level—reading the screen, and simulating key strokes. UI testing is notoriously tricky so we’ll have to figure out how to get there.

Conclusion

Our 1.0 party was a bit spoiled by this bug, and we are sorry that installation was disappointing to those of you who tried 1.0. We hope 1.0.1 will allow you to try and see what declarative and programmable system configuration management is like, because that’s where the real value of Guix System is—the graphical installer is icing on the cake.

Join us on #guix and on the mailing lists!

About GNU Guix

GNU Guix is a transactional package manager and an advanced distribution of the GNU system that respects user freedom. Guix can be used on top of any system running the kernel Linux, or it can be used as a standalone operating system distribution for i686, x86_64, ARMv7, and AArch64 machines.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. When used as a standalone GNU/Linux distribution, Guix offers a declarative, stateless approach to operating system configuration management. Guix is highly customizable and hackable through Guile programming interfaces and extensions to the Scheme language.

by Ludovic Courtès at May 19, 2019 09:30 PM

May 17, 2019

Programming Praxis

Is This Insane?

[ I’ve been very busy at work this week, and don’t have time to write a proper exercise. My apologies. ]

I stumbled across Twitter account ed1conf that included this method of collaborating with another user on an ed(1) session:

Have two ed(1) sessions open concurrently and want to easily transfer lines between them?

    $ ed -p"a)" a.txt

in another shell

    $ mkfifo fifo
    $ ed -p"b)" b.txt

then

    a) 15,21 w fifo

then

    b) 13r fifo

Can reuse the same fifo bidirectionally. Finally

    !rm fifo

I’m not sure if that’s brilliant or insane! Actually, I’m not even sure if a whole Twitter account devoted to ed(1) is brilliant or insane.

Perhaps you would like to share with us some other examples of brilliant insanity.

by programmingpraxis at May 17, 2019 09:00 AM

May 14, 2019

Programming Praxis

The Rat Eats The Cheese

A square maze contains cheese wedges on some of its squares:

·  ·  · 🧀  ·
·  ·  ·  ·  ·
· 🧀  · 🧀 🧀
·  · 🧀  · 🧀
·  ·  ·  · ·

[ Did you know there is a cheese-wedge character in Unicode? I didn’t. The center-dot is & # 183 ;, the cheese is & # 129472 ;, and I had to sprinkle in a few & thinsp ; characters to line things up. And of course to type those I had to add extra spaces, because WordPress is aggressive about turning them into characters. ]

A rat, starting at the lower left-hand corner of the maze, can move only up or right. What is the maximum amount of cheese the rat can eat?

Your task is to write a program to determine how much cheese the rat can eat. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at May 14, 2019 09:00 AM

Common Characters

Today’s exercise comes from a coding challenge site:

Given a list of words containing only lower-case letters, return a list of characters that appear in all the words, with multiplicity. For instance, given the words BELLA, LABEL and ROLLER, the characters E, L and L appear in all three words.

Your task is to return a list of characters that appear in all words of an input list. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at May 14, 2019 09:00 AM

May 10, 2019

Programming Praxis

The Recamán Sequence

I’ve been watching Numberphile again, specifically their episode about the Recamán sequence 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11, … A005132, defined as follows:

The Recamán sequence is an integer sequence R with R0 = 0 and Rn = Rn−1n if Rn = Rn−1n is positive and not already in the sequence and Rn−1 + n otherwise.

Your task is to write a program that generates the Recamán sequence; use your program to compute R1000000 (the one-million-and-first element). When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at May 10, 2019 09:00 AM

May 07, 2019

Programming Praxis

Identifying Squares, Revisited

Some algorithms require the ability to rapidly identify numbers such as 36 and 121 that are squares; for instance, in Fermat’s factoring algorithm, and variants derived from it, identifiying squares is the performance bottleneck of the procedure. A naive program computes the integer square root of the target number, squares it, and reports a square if it is equal to the original target:

def isqrt(n):
  if n < 1: return 0
  u, s = n, n+1
  while u < s:
    s = u
    t = s + n // s
    u = t // 2
  return s
def isSquare(n): # naive
  s = isqrt(n); return s*s == n

(We are using Python instead of Scheme for this exercise because bit-operators like & are easier to type than functions like bitwise-and.)

This is very slow because the calculation to compute the integer square root takes a long time. In a previous exercise, we looked at a method for reducing the number of integer square roots that need to be computed:

def isSquare(n): # fenderbender
  m = n & 127
  if ((m*0x8bc40d7d) & (m*0xa1e2f5d1) & 0x14020a): return False
  largeMod = n % (63*25*11*17*19*23*31)
  m = largeMod % 63
  if ((m*0x3d491df7) & (m*0xc824a9f9) & 0x10f14008): return False
  m = largeMod % 25
  if ((m*0x1929fc1b) & (m*0x4c9ea3b2) & 0x51001005): return False
  m = 0xd10d829a * (largeMod % 31) 
  if (m & (m+0x672a5354) & 0x21025115): return False
  m = largeMod % 23
  if ((m*0x7bd28629) & (m*0xe7180889) & 0xf8300): return False
  m = largeMod % 19
  if ((m*0x1b8bead3) & (m*0x4d75a124) & 0x4280082b): return False
  m = largeMod % 17 
  if ((m*0x6736f323) & (m*0x9b1d499) & 0xc0000300): return False
  m = largeMod % 11 
  if ((m*0xabf1a3a7) & (m*0x2612bf93) & 0x45854000): return False
  s = isqrt(n); return s*s == n

This is wicked fast because it computes residue classes based on small primes and quickly identifies numbers that cannot possibly be a square; fenderbender eliminates the expensive square root calculation in 99.92% of cases. But all those magic numbers make the function wicked, as well as wicked fast, and it is easy to make an editing error when copying the function to a new program (you will quickly and accurately guess how I know that).

Your task is to write a program that quickly identifies squares without all the magic numbers. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at May 07, 2019 09:00 AM

May 03, 2019

Programming Praxis

Three Homework Problems

The end of the school year is approaching in many places, and students are submitting their final homework assignment, so they ask questions on the internet. Here are three questions I have seen recently:

  1. Write a function adjoin-set that given a set of integers stored in a linked list in increasing order, and an integer to be inserted in the set, adjoins the integer to the set if it is not already in the set and returns the updated set.
  2. Write a function list-index that finds the index within a list where a given item occurs, or returns -1 if the item is not in the list.
  3. Write a function update-count that takes a list of key/count pairs and a key and increments the count of the given key, or adds a new key/count pair with count = 1 if the key is not present in the list.

Your task is to solve the three problems posed above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at May 03, 2019 09:00 AM

May 02, 2019

GNU Guix

GNU Guix 1.0.0 released

We are excited to announce the release of GNU Guix version 1.0.0!

The release comes with ISO-9660 installation images, a virtual machine image, and with tarballs to install the package manager on top of your GNU/Linux distro, either from source or from binaries. Guix users can update by running guix pull.

Guix 1.0!

One-point-oh always means a lot for free software releases. For Guix, 1.0 is the result of seven years of development, with code, packaging, and documentation contributions made by 260 people, translation work carried out by a dozen of people, and artwork and web site development by a couple of individuals, to name some of the activities that have been happening. During those years we published no less than 19 “0.x” releases.

The journey to 1.0

We took our time to get there, which is quite unusual in an era where free software moves so fast. Why did we take this much time? First, it takes time to build a community around a GNU/Linux distribution, and a distribution wouldn’t really exist without it. Second, we feel like we’re contributing an important piece to the GNU operating system, and that is surely intimidating and humbling.

Last, we’ve been building something new. Of course we stand on the shoulders of giants, and in particular Nix, which brought the functional software deployment paradigm that Guix implements. But developing Guix has been—and still is!—a challenge in many ways: it’s a programming language design challenge, an operating system design challenge, a challenge for security, reproducibility, bootstrapping, usability, and more. In other words, it’s been a long but insightful journey! :-)

What GNU Guix can do for you

Presumably some of the readers are discovering Guix today, so let’s recap what Guix can do for you as a user. Guix is a complete toolbox for software deployment in general, which makes it different from most of the tools you may be familiar with.

Guix manages packages, environments, containers, and systems.

This may sound a little abstract so let’s look at concrete use cases:

  • As a user, Guix allows you to install applications and to keep them up-to-date: search for software with guix search, install it with guix install, and maintain it up-to-date by regularly running guix pull and guix upgrade. Guix follows a so-called “rolling release” model, so you can run guix pull at any time to get the latest and greatest bits of free software.

    This certainly sounds familiar, but a distinguishing property here is dependability: Guix is transactional, meaning that you can at any time roll back to a previous “generation” of your package set with guix package --roll-back, inspect differences with guix package -l, and so on.

    Another useful property is reproducibility: Guix allows you to deploy the exact same software environment on different machines or at different points in time thanks to guix describe and guix pull.

    This, coupled with the fact that package management operations do not require root access, is invaluable notably in the context of high-performance computing (HPC) and reproducible science, which the Guix-HPC effort has been focusing on.

  • As a developer, we hope you’ll enjoy guix environment, which allows you to spawn one-off software environments. Suppose you’re a GIMP developer: running guix environment gimp spawns a shell with everything you need to hack on GIMP—much quicker than manually installing its many dependencies.

    Developers often struggle to push their work to users so they get quick feedback. The guix pack provides an easy way to create container images for use by Docker & co., or even standalone relocatable tarballs that anyone can run, regardless of the GNU/Linux distribution they use.

    Oh, and you may also like package transformation options, which allow you define package variants from the command line.

  • As a system administrator—and actually, we’re all system administrators of sorts on our laptops!—, Guix’s declarative and unified approach to configuration management should be handy. It surely is a departure from what most people are used to, but it is so reassuring: one configuration file is enough to specify all the aspects of the system config—services, file systems, locale, accounts—all in the same language.

    That makes it surprisingly easy to deploy otherwise complex services such as applications that depend on Web services. For instance, setting up CGit or Zabbix is a one-liner, even though behind the scenes that involves setting up nginx, fcgiwrap, etc. We’d love to see to what extent this helps people self-host services—sort of similar to what FreedomBox and YunoHost have been focusing on.

    With guix system you can instantiate a configuration on your machine, or in a virtual machine (VM) where you can test it, or in a container. You can also provision ISO images, VM images, or container images with a complete OS, from the same config, all with guix system.

The quick reference card shows the important commands. As you start diving deeper into Guix, you’ll discover that many aspects of the system are exposed using consistent Guile programming interfaces: package definitions, system services, the “init” system, and a whole bunch of system-level libraries. We believe that makes the system very hackable, and we hope you’ll find it as much fun to play with as we do.

So much for the overview!

What’s new since 0.16.0

For those who’ve been following along, a great many things have changed over the last 5 months since the 0.16.0 release—99 people contributed over 5,700 commits during that time! Here are the highlights:

  • The ISO installation image now runs a cute text-mode graphical installer—big thanks to Mathieu Othacehe for writing it and to everyone who tested it and improved it! It is similar in spirit to the Debian installer. Whether you’re a die-hard GNU/Linux hacker or a novice user, you’ll certainly find that this makes system installation much less tedious than it was! The installer is fully translated to French, German, and Spanish.
  • The new VM image better matches user expectations: whether you want to tinker with Guix System and see what it’s like, or whether you want to use it as a development environment, this VM image should be more directly useful.
  • The user interface was improved: aliases for common operations such as guix search and guix install are now available, diagnostics are now colorized, more operations show a progress bar, there’s a new --verbosity option recognized by all commands, and most commands are now “quiet” by default.
  • There’s a new --with-git-url package transformation option, that goes with --with-branch and --with-commit.
  • Guix now has a first-class, uniform mechanism to configure keyboard layout—a long overdue addition. Related to that, Xorg configuration has been streamlined with the new xorg-configuration record.
  • We introduced guix pack -R a while back: it creates tarballs containing relocatable application bundles that rely on user namespaces. Starting from 1.0, guix pack -RR (like “reliably relocatable”?) generates relocatable binaries that fall back to PRoot on systems where user namespaces are not supported.
  • More than 1,100 packages were added, leading to close to 10,000 packages, 2,104 packages were updated, and several system services were contributed.
  • The manual has been fully translated to French, the German and Spanish translations are nearing completion, and work has begun on a Simplified Chinese translation. You can help translate the manual into your language by joining the Translation Project.

That’s a long list already, but you can find more details in the NEWS file.

What’s next?

One-point-oh is a major milestone, especially for those of us who’ve been on board for several years. But with the wealth of ideas we’ve been collecting, it’s definitely not the end of the road!

If you’re interested in “devops” and distributed deployment, you will certainly be happy to help in that area, those interested in OS development might want to make the Shepherd more flexible and snappy, furthering integration with Software Heritage will probably be #1 on the to-do list of scientists concerned with long-term reproducibility, programming language tinkerers may want to push G-expressions further, etc. Guix 1.0 is a tool that’s both serviceable for one’s day-to-day computer usage and a great playground for the tinkerers among us.

Whether you want to help on design, coding, maintenance, system administration, translation, testing, artwork, web services, funding, organizing a Guix install party… your contributions are welcome!

We’re humans—don’t hesitate to get in touch with us, and enjoy Guix 1.0!

About GNU Guix

GNU Guix is a transactional package manager and an advanced distribution of the GNU system that respects user freedom. Guix can be used on top of any system running the kernel Linux, or it can be used as a standalone operating system distribution for i686, x86_64, ARMv7, and AArch64 machines.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. When used as a standalone GNU/Linux distribution, Guix offers a declarative, stateless approach to operating system configuration management. Guix is highly customizable and hackable through Guile programming interfaces and extensions to the Scheme language.

by Ludovic Courtès at May 02, 2019 02:00 PM

April 30, 2019

Programming Praxis

Hash Tables With Open Addressing

We have studied hash tables in several previous exercises, most of them of the “chaining” variety, where collisions are resolved by inserting each item in a linked list in the bucket to which it hashes. Today’s exercise looks at two different varieties of hash tables that use “open addressing,” in which all keys are stored in the buckets themselves, one key per bucket, with collisions resolved by moving them to a different bucket. We studied one type of open addressing in the exercise on cuckoo hashing, today we will see two others: linear probing and double hashing. Our hash tables consist of M memory addresses that hold N keys (or key/value pairs). Obviously, N must be less than M, and the load factor NM is critical to the performance of the algorithm; if the table becomes too loaded, search times increase dramatically. Open address hash tables work best when N can be predicted with some reliability, so an appropriate M can be chosen.

The linear probing algorithm hashes the key onto the range 0 .. M−1 and looks first in the indicated bucket. If the key is there, it is returned. If the bucket is empty, the key is not present in the table. If the bucket is non-empty, but the key doesn’t match, the search goes to the next bucket in order, wrapping around at the end of the table. Double hashing is similar, except that a second hash function determines the increment between probes. When double hashing, we must arrange that the increment is non-zero (otherwise the search will never visit any bucket except the first) and is co-prime to M (otherwise some buckets will never be visited), which is most easily arranged by making M prime.

Deletions require some care. We can’t just mark a bucket available when its key is deleted, because subsequent searches will miss keys that are beyond the newly-empty bucket. Instead, we mark the bucket with a special value showing that it is deleted, and consider that bucket to be non-empty but with a key that never matches.

Your task is to implement hash tables using linear probing and double hashing. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at April 30, 2019 09:00 AM

April 26, 2019

Programming Praxis

Common Words

Today’s exercise comes from Stack Overflow:

Given a text file like:

word1 word2 word3 word4
word4 word5 word6 word7
word6 word7 word8 word9
word9 word6 word8 word3
word1 word4 word5 word4

Write a program that returns those lines that have n words in common with the previous line. For instance, given the input above, the only output line would be:

word9 word6 word8 word3

The original question requested a solution in sed or awk, but you are free to use any language.

Your task is to write a program to extract lines from a text file that have n words in common with the previous line. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at April 26, 2019 09:00 AM

April 25, 2019

Greg Hendershott

Supporting multi-in

Supporting multi-in

:: Racket, Emacs

In racket-mode I improved support for the multi-in form provided by racket/require.

What is multi-in?

Instead of:

1
2
3
4
5
(require net/uri-codec
         net/url
         racket/contract
         racket/format
         racket/string)

You can say:

1
2
3
(require racket/require
         (multi-in net (uri-codec url))
         (multi-in racket (contract format string)))

One detail: The racket/require must appear before any multi-in forms. Any sorting must make an exception for this.

What are the racket-{tidy trim base}-requires commands?

  • racket-tidy-requires gathers multiple require forms into one. Within that, it groups phase level sub-forms such as for-syntax. Finally it sorts absolute module paths like foo before relative paths like "foo.rkt", and sorts each of those alphabetically.

  • racket-trim-requires uses the show-requires function from macro-debugger/analysis/check-requires to analyze requires and delete any unused. Also it tidies.

  • racket-base-requires uses the analysis to change a #lang racket file to #lang racket/base, adding requires as necessary. Also it trims and tidies.

What are the changes?

  1. Sorting makes sure to keep racket/require first.

  2. If racket/require is present in the original require form(s), then multi-in is used when tidying.

  3. Any analysis that says requires should be removed, should handle multi-in forms.

Essentially, the commands first “expand” or “explode” multi-in forms to individual requires, do any analysis and modifications, then try to “unexpand” or “implode” them back again.1

All together, these changes close issues 355, 356, and 369.

Example without racket/require

Here’s an example where racket/require is not in the original require forms:

1
2
3
4
5
6
7
#lang racket

(require net/url)
(require net/uri-codec)

;; Just some expressions using imported definitions
string-join ~a get-pure-port uri-decode (match-define (list n) (list 1))

After M-x racket-base-requires:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#lang racket/base

(require net/uri-codec
         net/url
         racket/format
         racket/match
         racket/string)

;; Just some expressions using imported definitions
string-join ~a get-pure-port uri-decode (match-define (list n) (list 1))

Example with racket/require

Here’s an example where racket/require is in the original require forms:

1
2
3
4
5
6
7
8
#lang racket

(require racket/require) ;new
(require net/url)
(require net/uri-codec)

;; Just some expressions using imported definitions
string-join ~a get-pure-port uri-decode (match-define (list n) (list 1))

After M-x racket-base-requires:

1
2
3
4
5
6
7
8
#lang racket/base

(require racket/require
         (multi-in net (uri-codec url))
         (multi-in racket (format match string)))

;; Just some expressions using imported definitions
string-join ~a get-pure-port uri-decode (match-define (list n) (list 1))
  1. Not everything survives a round-trip, exactly. A Cartesian product like (multi-in (a b) (c d)) will end up as a (multi-in a (c d)) and a (multi-in b (c d)) — equivalent but not as concise. 

by Greg Hendershott at April 25, 2019 12:00 AM

April 23, 2019

Programming Praxis

Triperfect Numbers

We have another exercise today based on a Numberphile video:

A perfect number is a number n that is equal to the sum of its divisors, excluding itself; in other words, a perfect number n satisfies the equation σn = 2n, where σ is the divisor-sum function. A triperfect number is a number n such that σn = 3n. It is believed that there are six, and only six, triperfect numbers.

Your task is to compute the six triperfect numbers. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at April 23, 2019 09:00 AM

April 19, 2019

Programming Praxis

Almost Primes

Today’s exercise was inspired by a task at Rosetta Code:

An integer n > 1 is a k-almost-prime if it is the product of k primes. Further, a k-almost prime is squarefree if all k primes are distinct.

You can learn more about k-almost-primes and their uses in number theory at Wikipedia or MathWorld.

Your task is to write programs that calculate the first ten k-almost-primes and squarefree k-almost-primes for 1 ≤ k ≤ 5. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at April 19, 2019 09:00 AM

April 16, 2019

Programming Praxis

The Last Prime Digit

Over at NumberPhile, Dr Grimes (can you look at him and not smile?) discusses the pattern in the last digits of successive prime numbers. It’s not what you think.

Your task is to write a program that mimics the calculations made by Dr Grimes. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at April 16, 2019 09:00 AM

April 12, 2019

Programming Praxis

Three Simple Math Problems

Here are three simple math problems. They are intended to be solved analytically, with number theory, without using a computer or a calculator. But I cheated. All three problems come from the YouTube channel Mind Your Decisions, where you will find lots of similar problems.

  1. Solve for x and y where both are integers: 615 + x2 = 2y
  2. Find a three-digit number abc = 100a + 10b + c with none of the digits 0 such that abc = a! + b! + c!
  3. Find a three-digit number pie = 100p + 10i + e with none of the digits 0 such that √pi + e = √ pie

Your task is to solve the three problems; you can write programs to solve them, if you wish, but it is fun to solve them by hand. When you are finished, you are welcome to or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

by programmingpraxis at April 12, 2019 04:00 AM