Probleme bei Tutorial (Programm zur Auflistung aller Primzahlen von 1 bis 100)



  • SeppJ schrieb:

    hustbaer schrieb:

    Kann ich überbieten:

    Das würde ich mal messen (mein Rechner ist aber im Moment zu ausgelastet für Benchmarks). ostream::operator<< ist schließlich überladen für C-Strings, daher sollte das eigentlich das gleiche sein.

    Es ging glaub' ich nicht um die Geschwindigkeit sondern um die Anzahl der Zeichen...

    Abgesehen davon muss die Aufgabe ja Berechnung aller Primzahlen von ... heißen.



  • Nö mir ging's schon um die Geschwindigkeit 🤡

    SeppJ schrieb:

    hustbaer schrieb:

    Kann ich überbieten:

    Das würde ich mal messen (mein Rechner ist aber im Moment zu ausgelastet für Benchmarks). ostream::operator<< ist schließlich überladen für C-Strings, daher sollte das eigentlich das gleiche sein.

    Na gut, dann halt

    static const char tfpnutoh[] = "2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97\n";
    fwrite(tfpnutoh, 1, sizeof(tfpnutoh) - 1, stdout);
    

    🤡 🤡


  • Mod

    Jetzt kommen wir dem Ziel einer nicht nur absichtlich falsch verstandenen sondern auch absolut unleserlichen Lösung näher. 👍

    P.S.: In C++ natürlich cout.write(...). Den dadurch erzeugten Overhead beim Startup für die Konstruktion des cout-Objektes würde nicht nicht mitzählen.



  • Ich glaub nicht das er noch irgendwas von dem Zeugs versteht, was ihr schreibt :p .



  • Da sein Problem ja schon gelöst wurde, sollte das OK gehen. Behaupte ich mal. Wenn nicht einfach schreien.

    Man könnte jetzt ne TMP Version basteln. Also komplett inklusive Konvertierung ins Dezimalsystem und Konkatenierung der Ergebnisse.

    fwrite(black_template_magic_primes<100>::str, 1, black_template_magic_primes<100>::strlen, stdout);
    


  • hustbaer schrieb:

    Da sein Problem ja schon gelöst wurde, sollte das OK gehen. Behaupte ich mal. Wenn nicht einfach schreien.

    Man könnte jetzt ne TMP Version basteln. Also komplett inklusive Konvertierung ins Dezimalsystem und Konkatenierung der Ergebnisse.

    fwrite(black_template_magic_primes<100>::str, 1, black_template_magic_primes<100>::strlen, stdout);
    

    Mein Unnötigkeitssensor schlägt wieder aus... oha, 6.9 - ich glaube gar, hustbaer sitzt da wirklich dran.



  • Hacker, überleg mal. Wie kann ein Sensor der - sich in deinem Besitz befindend - immer auf Anschlag steht noch weiter ausschlagen? Das kann nicht gehen.

    Und nein, ich sitze da nicht dran.

    Obwohl es auch nicht notwendigerweise "unnötig" wäre, zumindest nicht subjektiv betrachtet. Kann man einiges dabei lernen, bzw. üben wenn es Dinge sind die man schon kann, aber vielleicht länger nicht mehr angewendet hat.



  • hustbaer schrieb:

    Hacker, überleg mal. Wie kann ein Sensor der - sich in deinem Besitz befindend - immer auf Anschlag steht noch weiter ausschlagen? Das kann nicht gehen.

    Ich hab Alufolie rumgewickelt und bediene das ding durch eine Angel und einen Stock, aber der Zeiger zittert immer noch ein bisschen 🤡

    Außerdem mach' ich eigentlich nie unnötige Sachen. Ich bin - in gewissen Zeiten - recht rational.


  • Mod

    hustbaer schrieb:

    Man könnte jetzt ne TMP Version basteln. Also komplett inklusive Konvertierung ins Dezimalsystem und Konkatenierung der Ergebnisse.

    Ei, das ist wirklich übel hart. Da bin ich mir selbst nach einigem Nachdenken nicht sicher, ob das überhaupt geht. Ich glaube man braucht aber mindestens variadic templates. Habe gerade keine Zeit, mir das genauer anzugucken.



  • Variadic Templates waren noch nie erforderlich, sie sind einfach eine Vereinfachung für Typlisten, wie aus dem Alexandrescu bekannt.



  • Kellerautomat schrieb:

    sie sind einfach eine Vereinfachung für Typlisten, wie aus dem Alexandrescu bekannt.

    Das ist Sepp sicherlich bekannt. Aber es sind generische Typlisten 🤡



  • Was soll denn bitte eine generische Typliste sein?



  • Kellerautomat schrieb:

    Was soll denn bitte eine generische Typliste sein?

    Was ich meine ist folgendes: Ich dachte, du meinst, man kann statt

    template<typename ...c>
    void func(//.....
    

    Auch gleich das aufzurufende einsetzen.

    template<char a, size_t s, char b>
    void func(//...
    

    In diesem Fall ist aber (ich weiß nicht ob das Wort hier passt) oberes generischer, nicht?



  • Keine Ahnung, wovon du redest. Das hat damit überhaupt nichts zu tun. Hast du den Alexandrescu überhaupt gelesen? Falls nein -> großer Fehler.



  • SeppJ schrieb:

    Ei, das ist wirklich übel hart. Da bin ich mir selbst nach einigem Nachdenken nicht sicher, ob das überhaupt geht.

    Bitteschön.

    #include <iostream>
    #include <type_traits>
    
    template <bool B>
    struct bool_
    	: std::integral_constant<bool, B>
    {};
    
    template <unsigned I>
    struct unsigned_
    	: std::integral_constant<unsigned, I>
    {};
    
    template <typename A, typename B>
    struct dividable
    	: bool_<A::value % B::value == 0>
    {};
    
    template <typename A, typename B>
    struct or_
    	: bool_<A::value || B::value>
    {};
    
    template <typename I>
    struct increment
    	: unsigned_<I::value + 1>
    {};
    
    template <typename A, typename B>
    struct squared_less_equal
    	: bool_<(A::value * A::value <= B::value)>
    {};
    
    template <typename A>
    struct not_
    	: bool_<!A::value>
    {};
    
    template
    <
    	template <typename, typename> class Func,
    	typename Arg1
    >
    struct bind1st
    {
    	template <typename Arg2>
    	struct binder1st : Func<Arg1, Arg2>
    	{};
    };
    
    template
    <
    	template <typename, typename> class Func,
    	typename Arg2
    >
    struct bind2nd
    {
    	template <typename Arg1>
    	struct binder2nd : Func<Arg1, Arg2>
    	{};
    };
    
    template
    <
    	typename Init,
    	template <typename> class Cond,
    	template <typename> class Next,
    	template <typename> class Do,
    	template <typename, typename> class Combine,
    	typename Else
    >
    struct for_
    	: std::conditional
    	<
    		Cond<Init>::value,
    		typename std::conditional
    		<
    			Cond<Next<Init>>::value,
    			Combine
    			<
    				Do<Init>,
    				for_<Next<Init>, Cond, Next, Do, Combine, Else>
    			>,
    			Do<Init>
    		>::type,
    		Else
    	>::type
    {};
    
    template <unsigned I>
    struct is_prime
    	: not_
    	<
    		for_
    		<
    			unsigned_<2>,
    			bind2nd<squared_less_equal, unsigned_<I>>::template binder2nd,
    			increment,
    			bind1st<dividable, unsigned_<I>>::template binder1st,
    			or_,
    			bool_<true>
    		>
    	>
    {};
    
    template <>
    struct is_prime<2>
    	: bool_<true>
    {};
    
    template <>
    struct is_prime<3>
    	: bool_<true>
    {};
    
    template <char... S>
    struct string : std::identity<string<S...>>
    {
    	static char const c_str[];
    };
    
    template <char... S>
    char const string<S...>::c_str[] = { S..., 0 };
    
    template <typename S1, typename S2>
    struct append
    	: append<typename S1::type, typename S2::type>
    {};
    
    template <char... S1, char... S2>
    struct append<string<S1...>, string<S2...>>
    	: string<S1..., S2...>
    {};
    
    template <unsigned I>
    struct to_string
    	: std::conditional
    	<
    		I < 10,
    		string<I + '0'>,
    		append<to_string<I / 10>, string<I % 10 + '0'>>
    	>::type
    {};
    
    template <typename A, typename B>
    struct less
    	: bool_<(A::value < B::value)>
    {};
    
    template <typename I>
    struct to_string_if_prime
    	: std::conditional
    	<
    		is_prime<I::value>::value,
    		append<to_string<I::value>, string<' '>>,
    		string<>
    	>
    {};
    
    template <unsigned N>
    struct primes_below
    	: for_
    	<
    		unsigned_<0>,
    		bind2nd<less, unsigned_<N>>::template binder2nd,
    		increment,
    		to_string_if_prime,
    		append,
    		string<>
    	>
    {};
    
    int main()
    {
    	std::cout << primes_below<100>::type::c_str << '\n';
    }
    

    http://ideone.com/tswvn

    Man möge mir das überschüssige Whitespace am Ende verzeihen.


  • Mod

    Kellerautomat schrieb:

    http://ideone.com/tswvnMan möge mir das überschüssige Whitespace am Ende verzeihen.

    Sehr schöne Buchlösung, verliert aber Stilpunkte wegen for_ 😉

    Jetzt noch bitte eine Variante, bei der die Tiefe der rekursiven Instantiierung beschränkt ist auf sagen wir 10.



  • Kellerautomat schrieb:

    Keine Ahnung, wovon du redest. Das hat damit überhaupt nichts zu tun. Hast du den Alexandrescu überhaupt gelesen? Falls nein -> großer Fehler.

    Ja, hast Recht. Seh ich mir mal an.



  • Ist std::identity() das neue void main()?

    SCNR 😉



  • Furble Wurble schrieb:

    Ist std::identity() das neue void main()?

    SCNR 😉

    ?????

    Was sagt eigentlich SeppJ dazu? 😉



  • Ich schlage

    #!/usr/bin/make -f
    
    foo: foo.cc
    	$(CXX) $(CXXFLAGS) -o $@ $+
    
    primes.inl:
    	echo \"$(shell primes 1 100)\\n\" > $@
    
    foo.cc: primes.inl
    

    in der Makefile und

    #include <iostream>
    
    int main() {
      std::cout <<
    #include "primes.inl"
        ;
    }
    

    als foo.cc vor.


Anmelden zum Antworten