zadanie z ciagiem

0

Ciąg Collatz’a jest ciągiem danym następującym wzorem

c (n+1):
1/2c(n) gdy c jest nieparzyste
3
c(n) + 1 gdy c jest parzyste

Zauważ, że kolejne wyrazy ciągu Collatz’a mogą przyjmować różne wartości w zależności od wartości pierwszego wyrazu c0.

Przykład:
c0 = 20 C20 = (20, 10, 5, 16, 8, 4, 2, 1)
c0 = 19 C19 = (19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, . . . , 1)
c0 = 18 C18 = (18, 9, 28, 14, 7, 22, . . . , 1)

Napisz program, który wypisuje elementy ciągu Collatz’a zaczynającego się od podanej na wejściu programu
liczby całkowitej c0 będącej pierwszym wyrazem ciągu. Program powinien zakończyć wypisywanie, gdy wartość
kolejnego wyrazu będzie miała wartość równą 1.

**(zadanie na samym dole w pdf)
jestem totalnie początkująca, próbowałam kilka razy się za to zabrać, ale cały czas mam mnóstwo błędów, jakby jak zrobić żeby komputer wiedział, ze jest to ciag? bo wiem, że trzeba pętle zrobic dla kolejnych wyrazow parzystych i nieparzystych i to w sumie tyle. **

3

Kod poprawny, ale uprzedzam prowadzący przejrzy cię na wylot ...

#include <cstdio>
using namespace std;

int main(int n) 
{
	for(scanf("%d",&n);(printf("%d\n",n))&&(n!=1);n=n&1?(n<<1)+n+1:n>>1) {}
	return 0;
}

https://ideone.com/Xnn4by

2

W Ruscie, by nie było za łatwo:

use std::io;
use std::iter::Iterator;

struct Collatz(u64);

impl Iterator for Collatz {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        let n = self.0;

        self.0 = match self.0 {
            1 => 1,
            n if n % 2 == 0 => n / 2,
            n => 3 * n + 1,
        };

        Some(n)
    }
}

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let n: u64 = input.trim().parse().unwrap();

    for i in Collatz(n) {
        println!("{}", i);

        if i == 1 { return; }
    }
}

Teraz trzeba tylko to przetłumaczyć na C++. Powinnaś dać radę.

1

Jak Kodujesz funkcję rekurencyjną, to Odwzowowujesz w zasadzie defincję, plus warunek stopu (tu if (n == 1) return):

using namespace std;
void collatzSequence(int n) {
		cout << n << " ";
		if (n == 1) return;
		else if (n % 2 == 0) 
			collatzSequence (n / 2);
		else 
			collatzSequence(3 * n + 1);
}

int main(int argc, char **argv){
	
	collatzSequence(19);
    cout <<"\n";
	collatzSequence(20);
	cout <<"\n";
	return 0;
}

EDIT: Jeśli nie Chcesz używać rekurencji, bo, na przykład, Obawiasz się, że dla niektórych liczb, może nie "starczyć" stosu, to ten program można łatwo przepisać do wersji iteracyjnej:

void collatzSequenceIterative(int n) {
		cout << n << " ";
		while (n > 1) {
			if ( n % 2 == 0)
				n /= 2;
			else
				n = 3 * n + 1;
			cout << n << " ";
		}
}
1
#include <iostream>

void collatzSequence(unsigned n) {
    (void) (std::cout << n << ' ' , n == 1 || (collatzSequence(n & 1 ? (n << 1) + n + 1: n >> 1), 0));
}

int main() {
    std::cout << (collatzSequence(19) , '\n')
      << (collatzSequence(20), '\n');
}

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