Tegoroczne zadanie maturalne w różnych językach (wersja rekurencyjna)

1

Mam problem z Lispową wersją tegorocznego zadania maturalnego. Mam już wersje w:

  • C/C++
#include <cstdio>

unsigned int sklej(int n) {
  if(n == 1)
    return 1;
  if(n % 2 == 0)
    return n - 1 + 2*sklej(n/2);
  return n - 1 + sklej(n/2) + sklej((n+1)/2);
}

int main() {
  for(int i = 1; i < 10000; ++i)
    printf("%u\n", sklej(i));
  return 0;
}
  • Haskell
sklej n | n == 1 = 1
        | n `mod` 2 == 0 = n - 1 + 2 * sklej (n `div` 2)
        | n `mod` 2 /= 0 = n - 1 + sklej ((n-1) `div` 2) + sklej((n+1) `div` 2)

main = mapM (\x -> print $ sklej x) [1..10000]
  • OCaml
let rec sklej = function
  | 1 ->  1
  | n ->  if n mod 2 == 0 then
            n - 1 + 2 * sklej(n/2)
          else
            n - 1 + sklej((n+1)/2) + sklej((n-1)/2)
;;

for i = 1 to 10000 do
  Printf.printf "%d\n" (sklej i);
done;;
  • Pascal (fpc)
program Matura;

var
  i : Integer;

function sklej(n : Integer) : Int64;
begin
  if n = 1 then
    sklej := 1
  else if n mod 2 = 0 then
    sklej := n - 1 + 2 * sklej(n div 2)
  else
    sklej := n - 1 + sklej((n-1) div 2) + sklej((n+1) div 2);
end;

begin

for i := 1 to 10000 do
  writeln(sklej(i))
end.

Jednak w Lispie ciągle nie mogę tego wykombinować. Dopiero się go próbuję nauczyć ale coś mi słabo wyszło:

(defun sklej (n)
  if (= n 1) '1
    (if (evenp n) (* (- n 1) 2 (sklej (/ n 2)))
      (+ (- n 1) (sklej (/ (- n 1) 2)) (sklej (/ (+ n 1) 2)))))

(sklej 1)

PS Inne języki będą wkrótce :P

0

A o co właściwie chodzi w tym zadaniu? Przepisałem to "bezmyślnie" z implementacji w C na Lispa ale nie widzę sensownego zastosowania takiej funkcji (a może się mylę?)

(defun sklej (n)
  (cond
    ((= n 1) 1)
    ((evenp n) (+ (- n 1) (* 2 (sklej (truncate n 2)))))
    (t (+ (- n 1) (sklej (truncate n 2)) (sklej (truncate (1+ n) 2))))))

(dotimes (n 10000)
  (print (sklej (1+ n))))

W twoim kodzie:

  1. pierwsze if to nie S-Expression (zresztą cytowanie chyba niepotrzebne)
  2. (/ 3 2) wcale nie da 1 tylko 3/2 :) Trzeba używać rozwlekłej funkcji (truncate 3 2)
0

Ona ma niby liczyć długość ciągu znakowego zrobionego z połączenia wszystkich reprezentacji binarnych liczb od 1 do n-1.

1 użytkowników online, w tym zalogowanych: 0, gości: 1